WordPress.org

Ready to get started?Download WordPress

Forums

[resolved] WP_Query. Change posts order (5 posts)

  1. Motiejus Bagdonas
    Member
    Posted 1 year ago #

    Hello,
    I have a simple WP_Query loop, where I output posts by category. My problem is that I want to change the order of posts, for example:
    Post ID's: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
    to
    Post ID's: 8, 6, 3, 1, 2, 4, 5, 7, 9, 10
    So I took three posts, shifted them to the top and left others untouched. In general, what I would like to do, is to get an array of post ID's that corresponds to the current category, alter it and submit (to WP_Query?) before while have_posts() the_post() loop.
    I've searched this forum quite a while and the only thing I came up with was action hook pre_get_posts, but I guess it's wrong, because as I understood, this event is called before the query is submitted to the DB.
    Any suggestions/solutions to this problem?

  2. Spencer Cameron
    Member
    Posted 1 year ago #

    Hi motiejuss. I think Sort Query By Post In is what you're looking for. Once you activate this plugin, you can do something like this:

    $query = new WP_Query( array( 'orderby' => 'post__in', 'post__in' => array( 8, 6, 3, 1, 2, 4, 5, 7, 9, 10 ) ) );

    Does that fit the bill? :)

  3. Motiejus Bagdonas
    Member
    Posted 1 year ago #

    Thank you Spencer, this seems promising.
    I guess now I will have to make another loop before WP_Query in order to construct an Array with post ID's, right?

  4. Motiejus Bagdonas
    Member
    Posted 1 year ago #

    Ok, I got it working, thank you.
    Here's my working test example:

    <br />
    $all_posts = get_posts(array('numberposts' => -1, 'category' => $current_cat, 'orderby' => $orderby, 'order' => $order));<br />
    $all_post_ids = array();<br />
    foreach($all_posts as $post){<br />
      if(!in_array($post->ID, $sticky_post_ids)){<br />
        $all_post_ids[] = $post->ID;<br />
      }<br />
    }<br />
    $merged_all_post_ids = array_merge_recursive($sticky_post_ids,$all_post_ids);<br />

    Where $sticky_post_ids was a simple array with post ID's like: array(12, 54, 32).
    And my WP_Query args: array( 'orderby' => 'post__in', 'post__in' => $merged_all_post_ids ).

    And I had to modify the plugin function a bit, which now looks like this:

    <br />
    function sort_query_by_post_in( $sortby, $thequery ) {<br />
            global $wpdb;<br />
            if ( ! empty( $thequery->query['post__in'] ) && isset( $thequery->query['orderby'] ) && $thequery->query['orderby'] == 'post__in' )<br />
                    $sortby = "find_in_set(" . $wpdb->prefix . "posts.ID, '" . implode( ',', $thequery->query['post__in'] ) . "')";<br />
            return $sortby;<br />
    }<br />
    add_filter( 'posts_orderby', 'sort_query_by_post_in', 10, 2 );<br />
  5. Spencer Cameron
    Member
    Posted 1 year ago #

    The first part looks good, but I'm not sure you need to run the first query. It seems like an unnecessary performance hit. You're grabbing all the posts, then seeing which one's are sticky posts, right?

    If so, just start with the sticky posts to begin with. You already have the IDs.

    How about this:
    `$query = new WP_Query( array( 'orderby' => 'post__in', 'post__in' => $sticky_post_ids ) );

    Did I misunderstand?

    I'm glad you got it working, by the way! :)

Topic Closed

This topic has been closed to new replies.

About this Topic