I've a custom page template where I want to query 2 posts from a post type and 1 post from another post type. I have it set up like this:

$paged = get_query_var('paged') ? get_query_var('paged') : 1;

$articles = get_posts(array(
  'post_type' => 'articles',
  'numberposts' => 1,
  'posts_per_page' => 1,
  'paged' => $paged

$news = get_posts(array(
  'post_type' => 'news',
  'numberposts' => 2,
  'posts_per_page' => 2,
  'paged' => $paged

$all_posts = array_merge($articles, $news);

Then I do the loop:

<? foreach ($all_posts as $post): setup_postdata($post) ?>
  <? get_template_part('content') ?>
<? endforeach ?>

And finally I add pagination. I tried WP-PageNavi as well as regular WordPress functions.


When I go to the page I can see 3 posts as expected (1 article, 2 news) but there is no pagination. If I manually navigate to /page/2, /page/3, etc. it seems to work and show the next 3 posts but only the previous_posts_link shows up, not the next_posts_link or PageNavi.

The real world example is slightly more complicated and query_posts or WP_Query are not an option.

How to get pagination working properly?

  • 1
    pagination functions operate on the global $wp_query, WordPress has no knowledge of your custom queries and how many pages should exist, and wp_pagenavi needs a query object to read the max_num_pages. I think you'll have to build your own pagination from scratch based on the total number of posts available within each distinct query by querying via WP_Query to know how many posts are available to each query regardless of page.
    – Milo
    Mar 21, 2013 at 15:48
  • Why does page/2 page/3 work then...
    – elclanrs
    Mar 21, 2013 at 20:43
  • because adding a page number causes the global paged var to contain that number. the previous_posts_link function simply subtracts 1 from the value of paged. but the default query has no pages, which is why you never see a next_posts_link.
    – Milo
    Mar 21, 2013 at 21:22
  • @Milo. That's starting to make sense...
    – elclanrs
    Mar 21, 2013 at 21:42

1 Answer 1


Your $paged variable on the first is set in the main query. And there is just one page, because it is a page. The get_posts() calls don't affect that. So the number of all available pages is never higher than the current page, and you cannot get a next page link.

Solution: filter pre_get_posts and set your post types here.

  • pre_get_posts doesn't work for me in page templates. I tried the simplest example with The Loop in page-mypage.php and then if (is_page('mypage')) { $query->set('post-type', array('articles','news')); } and it doesn't work.
    – elclanrs
    Mar 21, 2013 at 21:50
  • This is similar to my problem but there's no asnwer stackoverflow.com/questions/15015316/…
    – elclanrs
    Mar 21, 2013 at 21:54
  • Also found this which is similar as well wpaustralia.org/topic/pre_get_posts-and-is_front_page. So I'm guessing checking for is_page doesn't work in pre_get_posts so I'm doing this $query->get('pagename') == 'mypage' and then set the query but still doesn't work.
    – elclanrs
    Mar 21, 2013 at 21:58

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.