1

I have a custom post type that have a meta_key custom_meta_sponsored that owns alphabetical values. "X" means post doesn't sponsored. I want to show the archive page in custom order, sponsored first in random order.

I use pre_get_posts hook, but it doesn't work as I expected:

function custom_loops($query) {
    if ( is_post_type_archive('my_post_type') ){
        $query->set( 'posts_per_page', 40);
        $query->set( 'meta_key', 'custom_meta_sponsored');
        $query->set( 'orderby', 'meta_value rand');
        //$query->set( 'order', 'DESC');
    }
    remove_action( 'pre_get_posts', 'custom_loops' );
}
add_action('pre_get_posts', 'custom_loops');

In the result sponsored posts display first and nearly random. I mean sponsored posts in randon by a kind of date order. Newly created posts are always display first. I would like to display sponsored post fully random regardless of creation date. Any idea?

  • You'll need two loops – kraftner Jan 24 '15 at 9:54
  • Dear kraftner, could you please give me some instructions how to solve two loops. thanks. – user9909 Feb 10 '15 at 15:30
1

You could use the 'posts_orderby' filter:

function custom_loops($query) {
    if ( is_post_type_archive('my_post_type') ){
        $query->set( 'posts_per_page', 40);
        $query->set( 'meta_key', 'custom_meta_sponsored');
        $query->set( 'orderby', 'custom_meta_sponsored');
        $query->set( 'order', 'DESC');
        add_filter( 'posts_orderby', function ( $orderby, $query ) {
            if ( $query->get( 'orderby' ) != 'custom_meta_sponsored' ) return $orderby;
            global $wpdb;
            $orderby = $wpdb->prepare(
                'CASE WHEN ' . $wpdb->postmeta . '.meta_value != %s THEN CONCAT(%s, RAND()) ELSE '
                . $wpdb->posts . '.post_date END ' . $query->get( 'order' )
                , 'X', 'z'
            );
            return $orderby;
        }, 10, 2 );
    }
    remove_action( 'pre_get_posts', 'custom_loops' );
}
add_action('pre_get_posts', 'custom_loops');
  • It almost works posts display in fully random order, but some posts appear on first and second pages as well. :/ Probably I should use two loops in the template file. Could you please give me some instructions how to do this? – user9909 Jan 25 '15 at 8:10
  • Oh I just noticed non-sponsored are "X", not 0 - need to change CASE WHEN to check for this - will update answer... – bonger Jan 25 '15 at 9:45
0

Finally I created two loops. With a foreach I go through the main query results $wp_query->posts and reordering posts.

Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.