0

This is related to this other question, I tried with get_posts, pre_get_posts, WP_Query and basically every option I could find for 2 days now, no solution yet.

The full problem in hand: I have 2 post-types, articles and news. A post from "news" can be "featured" or "non-featured". I need to query 1 featured news, 4 articles and 2 non-featured news, and display them on a page in that order. The page uses the page-mypage.php template.

The posts need to be in that specific order because the size of the post changes depending on the type and the "featured" meta option. My grid is using Masonry and the sequence that works to have a full grid (no holes or weird empty space) is featured, article, article, article, article, non-featured, non-featured.

With the get_posts approach in the other question I can't get the pagination working. It works when navigating to /page/X but I tried a bunch of custom pagination solutions that didn't work and paginate_links which I couldn't get to work either.

So now I'm thinking of using a regular WP_Query but how do I tell WordPress I want that many posts from each post-type and in that particular order?

Here's what I really want to do but I can't seem to find a way to do it with WP_Query to make pagination work properly (damn pagination!):

$articles = get_posts(array(
  'post_type' => 'articles',
  'numberposts' => 4
));

$featured = get_posts(array(
  'post_type' => 'news',
  'numberposts' => 1,
  'meta_query' => array(
    array(
      'key' => 'featured-news',
      'value' => 'Yes',
      'compare' => 'LIKE'
    )
  )
));

$non_featured = get_posts(array(
  'post_type' => 'news',
  'numberposts' => 2,
  'meta_query' => array(
    array(
      'key' => 'featured-news',
      'value' => 'No',
      'compare' => 'LIKE'
    )
  )
));

// Merge in the order I need them to appear
$all_posts = array_merge($featured, $articles, $non-featured);

// The loop

Halp!.

1 Answer 1

0

You can use WP_Query() with paged array key to pass the current page number:

<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
        'post_type' => 'articles',
        'posts_per_page' => 4,
        'paged' => $paged
    );
$articles = new WP_Query($args);
////////////////////////////////
$args = array(
        'post_type' => 'news',
        'posts_per_page' => 1,
        'meta_query' => array(
            array(
                'key' => 'featured-news',
                'value' => 'Yes',
                'compare' => 'LIKE'
            )
        ),
        'paged' => $paged
    );
$featured = new WP_Query($args);
////////////////////////////////
$args = array(
        'post_type' => 'news',
        'posts_per_page' => 2,
        'meta_query' => array(
            array(
                'key' => 'featured-news',
                'value' => 'No',
                'compare' => 'LIKE'
            )
        ),
        'paged' => $paged
    );
$non_featured = new WP_Query($args);
////////////////////////////////
$articles = objectToArray($articles); // objectToArray() function defines below
$featured = objectToArray($featured);
$non_featured = objectToArray($non_featured);
$all_posts = array_merge($featured, $articles, $non_featured);
?>

And because you are query-ing from 3 post types, pagination will fail, because it doesn't know from which post type pagination should be based on!

You can use a manual pagination:

<?php
// $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
if($paged > 1)
{
    echo "<a href=\"".home_url('/')."/page/".($paged-1)."\">Previous page</a>";
}
echo "<a href=\"".home_url('/')."/page/".($paged+1)."\">Next page</a>";
?>

Maybe you want change the HREF attr to something else.

Which I forgot:

<?php
    function objectToArray($d) {
        if (is_object($d)) {
            $d = get_object_vars($d);
        }
        if (is_array($d)) {
            return array_map(__FUNCTION__, $d);
        }
        else {
            return $d;
        }
    }
?>

WP_Query returns a stdClass Object, first you should convert it to an array like below:

<?php
    $articles = objectToArray($articles);
    $featured = objectToArray($featured);
    $non_featured = objectToArray($non_featured);
?>

Then merging them. (updated code above)

Updated

Another handy way is merging stdClass Objects: https://stackoverflow.com/a/1953077/1906508

5
  • Mmmm, are you sure you can merge WP_Query objects like that. I tried something like this already. I'm using Pagenavi but I'll have a look at the custom pagination.
    – elclanrs
    Mar 22, 2013 at 8:18
  • @elclanrs updated my post.
    – revo
    Mar 22, 2013 at 8:40
  • Now that looks better, but what's the point of using WP_Query if I end up using a foreach with an array? I could also merge posts without objectToArray like this I guess: $all = array_merge($articles->posts, $featured->posts, $non_featured->posts).
    – elclanrs
    Mar 22, 2013 at 8:45
  • @elclanrs that's your force! i don't know which method u care and u want to show the results, but u want posts_per_page argument different for each post_type. Also you'd better see this : wordpress.stackexchange.com/questions/71576/… Also I added a link at the end of my answer.
    – revo
    Mar 22, 2013 at 8:56
  • I end up not doing this after all, found a better solution with Masonry. The pagination helped tho. Thanks.
    – elclanrs
    Mar 23, 2013 at 7:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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