• Resolved GenericBox

    (@genericbox)


    Hi WordPress,

    I was hoping to get some help with a custom query I am writing for a gallery system on my site.

    The problem is, my content is split across multiple post types, and while my query is pulling in all the content fine, one of my post types has nearly 1,000 entries.

    Therefore, the query is returning hundreds of entries from the one post type before it happens to return one from another post type which has relatively few entries (10-30).

    So, is there a way to keep the results orderby “random” but prioritise (or better yet deprioritise) the actual post_types so that the less populated post_types appear closer to the start of the query results?

    My query is written below (disregard the $filter variable — I have also implemented a filter system):

    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    $filter = esc_sql($_GET['filter']);
    $pts = array('pt1','pt2','pt3','pt4');
    if(!in_array($filter, $cats)) $filter = $cats;
    $args = array('post_type'	=> $filter,
    	      'posts_per_page'	=> 8,
    	      'paged'		=> $paged,
    	      'orderby'		=> 'post_type rand',
    	      'post_status'	=> 'publish');
    $the_query = new WP_Query;
    $the_query->query($args);

    I have changed the variable names/custom post type names.

    Thanks for any help you can provide.

    Regards,
    GenericBox

Viewing 4 replies - 1 through 4 (of 4 total)
  • Here’s one way to do it:

    This is untested, but you get the idea:

    $arr = array();
    
    foreach( array( 'pt1', 'pt2', 'pt3', 'pt4') as $pt )
    {
        $args = array(
                               'post_type' => $pt,
                               'posts_per_page' => 8,
                               'paged' => $paged,
                               'orderby' => 'rand',
                               'fields' => 'ids',
                     );
    
        $arr = $arr + get_posts( $args );
    }
    
    // get 8 random entries
    $ids = array_rand( $arr, 8 );
    
    $args = array( 'posts__in' => $ids );
    
    $the_query = new WP_Query( $args );

    i.e. we fetch 8 random post ids for each of your post type, collect them into an array,
    and then we select 8 random entries from that array and feed it into WP_Query().

    That way you can the give same probability of selecting a post from each post type (assuming there are at least 8 posts in each post type).

    Thread Starter GenericBox

    (@genericbox)

    Thanks for your response Birgire, the method makes sense. Thanks alot.

    I will implement it now and let you know how it works, and if I have to tweak it in any way.

    Regards,
    GB.

    Thread Starter GenericBox

    (@genericbox)

    Figured it out!

    It’s a little messy, and not as controllable as I would have liked – but its working, and the site for the client is a campaign landing page so will only be live for a few weeks/months anyway.

    If anyone has a similar issue, of wanting to handle different WP_Query arguments from multiple Custom Post Types in the one loop, maybe this will help you out. IT IS VERY BESPOKE however, and I doubt much of it will make sense, but I tried to comment as much as I could.

    I also ran into issues because I was using a plugin called WPML for translation into 3 different languages.

    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; // Get the page value
    $filter = get_query_var('filter'); // Get filter query var from permalink
    $langs = array('en','fr','nl'); // Define languages
    $notlangs = array_diff($langs, array(ICL_LANGUAGE_CODE)); // Create a new array from the languages minus the current language
    foreach($notlangs as $l) $lids[] = get_category_by_slug($l)->cat_ID; // Get the category IDs of the languages
    $pts = array('pt1','pt2','pt3','pt4'); // My Custom Post Types
    if(!in_array($filter, $pts)) $filter = array_diff($pts, array('pt1')); // Due to the conflicts with WPML, pt1 was causing the issues, so if the filter is all (as in, it isn't just "one" of the defined $pts, remove pt1 from the filter list
    
    // This is the main query - if $filter is just one post_type it runs as normal, if not, it is post_types minus pt1
    $args = array('post_type'	=> $filter,
    	      'posts_per_page'	=> 8,
    	      'paged'		=> $paged,
    	      'orderby'		=> 'menu_order',
    	      'post_status'	=> 'publish',
    	      );
    
    // This is the second query - this is for pt1 specifically, and has different args
    $eargs = array('post_type'	=> 'pt1',
    	       'posts_per_page'	=> 8,
    	       'paged'		=> $paged,
    	       'category__not_in' => $lids,
    	       'suppress_filters' => true
    	       );
    
    $the_query = new WP_Query; // Create the main query
    if($filter=='pt1') $args=$eargs; // If the filter is for just pt1 by itself, make the pt1 specific args the main args
    $the_query->query($args); // Run the standard WP loop query
    if(is_array($filter)) { // If $filter is an array, meaning it is not JUST a single filter
    	$ent_query = new WP_Query; // Create a new WP Query
    	$ent_query->query($eargs); // Run the query with pt1 args, effectively running two simultaneous queries
    	$the_query->posts = array_merge($the_query->posts, $ent_query->posts); // So then merge the two results into array, the original, "main" WP query
    	$the_query->post_count = count($the_query->posts); // So that the page count isn't broken by the merge, recount the query
    	shuffle($the_query->posts); // Randomise the results so it isn't 8 of each in a row
    }

    Because the 3 less populated post_types are queried first, the top part of my gallery is now garuanteed to be populated by them first, and the shuffle after each merge ensures I get a nice random pattern until they disappear normally when there is no more left for that page.

    I know this is highly specific – but hopefully some of the logic helps someone.

    The important part is running two queries simultaneously and then merging both of those results into the original main query.

    Thanks again Birgire, you got me thinking on the right track.

    Regards,
    GB.

    Good to hear you solved it,

    thanks for reporting back and sharing your code.

    cheers

Viewing 4 replies - 1 through 4 (of 4 total)
  • The topic ‘WP_Query Priority Ordering’ is closed to new replies.