Post Indexer Custom Query

I am using network_query_posts() to do a custom query of Post Indexer. So far, things have been going as expected, but have run into a couple spots where I cannot pull post info like that on the actual site itself. I had an issue with getting the correct post publish date, but have that figured out now, however, I ran into another issue with getting terms from custom taxonomies.

I have been using the below with success on the individual sites within the loop, however, when I try to query Post Indexer it does not return any values.

$post_main_terms = get_the_terms($postID, 'main-categories');
if (!empty($post_main_terms)){
	$post_main_term = array_shift($post_main_terms);
	$post_main_cat = $post_main_term->name;
}

I have tried numerous things, including using network_get_the_terms(), etc (too many to put on here), but nothing is returned for the value of the terms. So, would you be able to help me out with what I need to do in order to retrieve values of custom post categories/taxonomies?

Also, is there any documentation on more things like this to be able to pull info from each post Post Indexer indexes using the network_query_posts()?

Also, to make sure I have this setup correctly, this is what I am using for my query:

<?php
$args = array(
	'post_type'		=> 'post',
	'category_name'	=> 'name'
);

network_query_posts($args);
if ( network_have_posts() ) {
	while ( network_have_posts() ) {
		network_the_post();

			// Content here for each post

}

network_reset_postdata();
?>
  • Brent

    Naturally, after searching and testing/troubleshooting "solutions" for a couple of days, and posting this question, I found a similar solution I was able to modify for my needs. This is working, and displays the selected term for the custom category/taxonomy correctly. I just want to make sure this is a good approach/solution. Also, do I need the network_reset_postdata() at the end, as this is on a page with other querys? FYI, one of my custom taxomonies is named "main-categories"

    <?php
    	$args = array(
    		'post_type'	=> 'post',
    		'tax_query' => array(
    							array(
    								'taxonomy'	=> 'main-categories',
    								'field'		=> 'slug',
    								'terms'		=> 'tax-slug-name'
    							)
    						)
    	);
    
    	network_query_posts($args);
    	if ( network_have_posts() ) {
    		while ( network_have_posts() ) {
    			network_the_post();
    
    			$post_main_terms = network_get_the_terms($network_post->BLOG_ID, $network_post->ID, 'main-categories');
    				if (!empty($post_main_terms)){
    					$post_main_term = array_shift($post_main_terms);
    					$post_main_cat = $post_main_term->name;
    				}
    
    			?>
    
    				HTML stuff here for each post found
    
    			<?php
    
    			// This resets the variable to be empty before going to the next post
    			$post_main_cat = '';
    		}
    	}
    	network_reset_postdata();
    ?>
  • Brent

    Again, thank you for the follow up. I did, however, run into an issue with my code above. Again, I am using this query on the main website to bring in posts across the entire network - then order them accordingly by date.

    In calling the below two items there was an issue as two blog posts, each on a different multisite, have the same post ID. The post with the latest publish date works fine. The next post that has the same ID associated with it (both have a post ID of 18) shows up in the correct spot, but uses/shows the permalink and publish date of the first post with that ID of 18. So, if I click on the second post it actually goes to the correct blog/site, just not the right post. Example:

    URL of first blog post with same ID in the output list
    http://firstblog.example.com/2016/06/this-is-the-url-of-the-first-post

    URL of second blog post with same ID in the output list
    http://secondblog.example.com/2016/06/this-is-the-url-of-the-first-post

    This is what I am using to get these values per blog post in my query above:

    // What I am using to get the permalink - works unless posts have same ID
    network_get_permalink();
    
    // Only way I was able to get the correct publish date working in network loop
    $postID = network_get_the_ID();
    get_the_time('n/j/y', $postID);

    Any ides?

  • Panos

    Hey Brent ,

    By using the post id you can't be really sure in multisite, as that ID seems to be the id the post has in each subsite.

    I would suggest something like the following:

    $html = '';
    
        $args = array(
            'post_type' => 'post'
        );
    
        $network_posts = network_query_posts($args);
    
        foreach( $network_posts as $network_post ){
            ob_start();
    
            $ID = $network_post->ID;
            $date = $network_post->post_date;
            $guid = $network_post->guid;
            ?>
    
            <div>
    
                <h3><?php _e( $network_post->post_title )  ?></h3>
    
            </div>
    
            <?php
            $html .= ob_get_clean();
    
        }
    
        network_reset_postdata();

    Alternatively, if you want to use the post id, you can do so by using switch_to_blog( $blog_id ). Then any queries will be made regarding the specific subsite. When done you can use the restore_current_blog() to return to main blog.

    Hope this helps!

    Thanks!
    Panos

  • Brent

    Thank you. I got the above to work, after I took out the $html parts. Otherwise it was not producing anything. I also tried using the switch to blog, but for some reason that was not fetching any items either. I'm sure this was user error, but have not worked with that much, so was doing some trial and error.

    With that said, if I go the route you originally laid out I need a few things from the query. If you could help me with how to fetch each that would be great:

    • Author's First Name
    • Author's Last Name
    • Permalink (the pretty permalink, not the default with the "p=")
    • Post Date in this format: 7/6/16
    • Taxonomy names the post is in (I have multiple custom taxonomies - I need to query the name that each post has selected in a specific taxonomy - below is how I was doing that for one of the taxonomies)

    $post_main_terms = network_get_the_terms($network_post->BLOG_ID, $network_post->ID, 'main-categories');
    if (!empty($post_main_terms)){
    	$post_main_term = array_shift($post_main_terms);
    	$post_main_cat = $post_main_term->name;
    }

    This would check if there was an item selected in this specific taxonomy. If there was, then it would assign it to the variable $post_main_cat. I have a number of custom taxonomies that need to be checked if the post has a value or not.

  • Panos

    Hi Brent ,

    Regarding the $html var, did you try echo $html and didn't display anything?

    As for the $guid, I am afraid that only this is stored in the network_posts table. In order to show the permalink we will have to use the switch to blog. Please paste the following code in your child theme's functions.php file:

    function wpmudev_network_posts_sh( $atts ) {
    
        $html = '';
    
        $args = array(
            'post_type' => 'post'
        );
    
        $network_posts = network_query_posts($args);
    
        foreach( $network_posts as $network_post ){
    
            $blog_id = $network_post->BLOG_ID;
    
            switch_to_blog( $blog_id );
    
            ob_start();
    
            $ID = $network_post->ID;
    
            $post = get_post( $ID );
    
            $excerpt = isset( $post->post_excerpt ) && $post->post_excerpt != '' ? $post->post_excerpt : wp_trim_words( $post->post_content );
    
            $author_id = $post->post_author;
    
            $date = $post->post_date;
    
            $term_args = array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'all');
    
            $terms = wp_get_post_terms( $ID, 'category', $term_args );
    
            $terms_str = '';
            foreach( $terms as $term ){
    
                $terms_str .= '<a href="' . str_replace( '/blog', '', get_term_link( $term->term_id ) ) . '" class="network-post-term">' . __( $term->name ) . '</a>';
    
            }
    
            ?>
    
            <div class="network-post">
    
                <div class="network-post-date-author-metas">
                    <span class="network-post-author"><?php echo get_the_author_meta( 'user_nicename', $author_id ); ?></span> |
                    <span class="network-post-date"><?php echo $date ?></span>
                </div>
    
                <h3><a href="<?php echo get_permalink( $ID ); ?>"><?php _e( $post->post_title ); ?></a></h3>
    
                <div class="network-post-excerpt">
                    <?php _e( $excerpt ); ?>
                </div>
    
                <div class="network-post-terms">
    
                <?php echo $terms_str; ?>
    
                </div>
    
            </div>
    
            <?php
            $html .= ob_get_clean();
    
            restore_current_blog();
    
        }
    
        network_reset_postdata();
    
        return $html;
    }
    
    add_shortcode( 'wpmudev_network_posts', 'wpmudev_network_posts_sh' );

    You can use the shortcode [wpmudev_network_posts] in any page to see the output.

    It should contain most of the metas you need :slight_smile:

    Hope this helps!

    Cheers!
    Panos

  • Ritesh

    Hi Brent

    I hope you are having a good day :slight_smile:

    I have checked your site and installed Query monitor plugin using which I have determined that it's querying for 10 posts only which is set in settings to show number of posts.

    Please make sure you have set $args as following:

    $args = array(
            'post_type' => 'post',
            'posts_per_page' => 12,
        );

    To debug it more, I will need to check the template and shortcode code you are using. As I can't edit page template via dashboard, I will need to ask for FTP details of your site in order to debug it further.

    You can send FTP details privately through our contact form: https://premium.wpmudev.org/contact/

    Select "I have a different question" for your topic - this and the subject line ensure that it gets assigned to me :slight_smile:

    Send in:

    Subject: "Attn: Ritesh Patel"
    -WordPress admin username
    -WordPress admin password
    -login url
    -FTP credentials (host/username/password)
    -link back to this thread for reference
    -any other relevant urls

    **If you keep support access active then no need to send in wp-admin

    Cheers,
    Ritesh

  • Brent

    New one with this query deal. I am allowing people that have an account the ability to create articles from the front end of the site, using wp_insert_post(). That is working just fine, and entering into the admin/database fine - everything is saving, I can view the page, etc. However, they are not showing up in my query results from above. I see that the Post Indexer has indexed them from the results in the site admin, but they don't show up. I tested just adding a new post via the admin panel, so not on the front end form submission, and bam - that post instantly shows up with my query results. Thoughts?

  • Brent

    Just an FYI, when I go back into the admin area, and hit Update on the article entered from the front end, without making any changes to it, the post shows up in the query results. I'm thinking that I am either missing something in my wp_insert_post(), or even though in the admin the custom taxonomies are shown as being selected, there is something not final with that that is causing the issue. I did a general query without calling a specific taxonomy, and the result had the submissions from the front end. So, it has to be in how I am saving taxonomy selections from the front end.

  • Brent

    They have not. Again, they work with getting all the info into the admin when created from the front end submission form, including getting the correct custom taxonomies selected, however, they do not show up in the network query. When I check Post Indexer it does show that these new posts have been indexed, but they only show up in the query if I go back into the admin and hit the update button.

    You currently have support access to the site, would you like to check out the file as well? I can provide that info, but obviously would need to email/privately provide that info to you.

  • Panos

    Hi Brent ,

    As Sajid already mentioned these pagination functions won't work I'm afraid.

    The only way to achieve pagination here with some custom functionality to get the total number of posts and custom pagination functions. The trickiest part is to get the total number of posts. You can achieve this with one of the following options:

    Note:
    All following options are aiming to retrieve the total number of posts. They require custom pagination links and functions to get the current page

    A. Do double queries, first one is for COUNT, it can even be a custom like:

    global $wpdb;
    $posts_count = $wpdb->query("SELECT COUNT(*) FROM {$wpdb->base_prefix}network_posts WHERE .... ");
    
    $max_num_pages = ceil( $posts_count / $posts_per_page );

    The args could be like:

    $posts_per_page = 10;
    $paged = (int)$_GET['page'];
    $args = array(
            'post_type' => 'post',
            'posts_per_page' => $posts_per_page,
            'paged' => $paged
        );

    B. Using a custom query with "SELECT SQL_CALC_FOUND_ROWS ...." so you do not need double queries.

    C. This one also requires to change the method we followed. So instead of using:
    $network_posts = network_query_posts($args)
    You can use:

    $posts_per_page = 10;
    $paged = (int)$_GET['page'];
    
    $network_query = new Network_Query;
    
        $network_query->set( 'post_type', 'post' );
        $network_query->set( 'posts_per_page', $posts_per_page );
        $network_query->set( 'paged', $paged );
    
        $network_posts = $network_query->get_posts();
    
    $posts_count = $network_query->found_posts;
    
    $max_num_pages = ceil( $posts_count / $posts_per_page );

    I think I would go with method C, you can test all three of them and decide which fits you bets!

    Hope you find this information useful :slight_smile:

    Thanks!
    Panos

  • Brent

    Thank you, Panos. C is working in generating my query/results, however, I still cannot get the pagination to show up, and I'm assuming it's because I need some type of custom pagination code. Right now I am still trying to add next_posts_link() and previous_posts_link() with my $html output. Is there some other code I need to use to make the Next/Previous links to show up like an archive page would?

    Which brings me to another question...can I utilize an archive.php (or category, taxonomy, or tag) template instead for the posts in Indexer? This obviously then generates the pagination by default, etc.

  • Panos

    Hi Brent ,

    Since it's not in a wp loop these functions won't work. But you can use the "paginate_links()":
    You should alread have the current page ($paged variable ) and how many posts per page you need:

    $paged = ( get_query_var( 'paged' ) ) ? absint( get_query_var( 'paged' ) ) : 1;
    $post_per_page =10;

    After the line where you get the posts:
    $network_posts = $network_query->get_posts();

    you can get the max number of pages:
    $max_num_pages = ceil( $network_query->found_posts / $post_per_page );

    Since you have these set and accessible you can show the pagination links:

    $big = 999999999;
    
    echo paginate_links( array(
        'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
        'format' => '?paged=%#%',
        'current' => $paged,
        'total' => $max_num_pages
    ) );

    Hope this helps!

    Cheers!
    Panos

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.