0

In a custom page template, I use the following code to display posts from that category and sub-category.

How do I make the pagination work?

// The Query
query_posts( array ( 'category_name' => 'publicatii', 'posts_per_page' => 4 ) );

// The Loop
while ( have_posts() ) : the_post();
    echo '<h1>';
    the_title();
    echo '</h1>';
    the_excerpt();
    echo ' <p class="postinfo">Written by: ';
    the_author_posts_link();
    echo 'Posted on ';
    the_date();
    echo 'Categories: ' ;
    the_category( ', ' );
    echo '</p>' ;
endwhile;

global $wp_query;

$big = 999999999; // need an unlikely integer

echo paginate_links( array(
    'base'    => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
    'format'  => '?paged=%#%',
    'current' => max( 1, get_query_var( 'paged' ) ),
    'total'   => $wp_query->max_num_pages
) );

// Reset Query
wp_reset_query();

get_footer();

As an example, it does change the link (page/2/ ... page/3/), but it does not change the posts from that page (still the same posts).

2
  • 1
    query_posts should never be used, under any circumstances, and is the primary reason behind your lack of pagination. There are better ways of querying for posts or changing the posts WordPress displays
    – Tom J Nowell
    Commented Nov 8, 2015 at 0:21
  • Can you give me an example? Commented Nov 8, 2015 at 0:24

1 Answer 1

2

The root of your problem is the call to query_posts. You're asking WordPress to load a page and template, and pull posts from the database, then throw away those queries, and repeat them all over again but with new parameters.

It's like asking a PA for a cup of tea every morning, then throwing it away and saying you actually wanted coffee. It's easier to just ask for coffee the first time.

The new problem here is that WordPress had handled the pagination for you, but you've just thrown it all away, and the query you've replaced it with has no concept of pagination. If you're on page 2, how would it know? You haven't passed in the page 2 option into your query, so it always shows page 1, as you asked it to.

So instead, you should use the pre_get_posts filter. This filter runs before WordPress goes to the database and lets you change the variables passed in. E.g.

// only show 4 posts per page on the homepage
function homepage_set_posts_per_page( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'posts_per_page', 4 );
    }
}
add_filter( 'pre_get_posts', 'homepage_set_posts_per_page' );

You can set and unset the query options this way, and use get and other methods to do more specific checks

If you ever have to display posts that aren't in the main query/loop, perhaps for a widget or a sidebar, you should use the WP_Query object. e.g.

// lets query the DB for pages
$loop = new WP_Query( array(
    'post_type' => 'page'
));
// did we find posts?
if ( $loop->have_posts() ) {
    // yes we did! yay
    while( $loop->have_posts() ) {
        $loop->the_post();
        // display each post
    }
    // clean up after our loop
    wp_reset_postdata();
} else {
    // no posts found, we don't need to cleanup, but we should probably tell the user we found nothing
}

On the other hand, you could just point users to the /category/publicatii and implement a category-publicatii.php in your theme and sidestep all the hacking queries etc

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.