Query with pre_get_posts to get pagination

It appears that you want to create a custom page template to display a custom post type? If so, you don’t really need to mess with pre_get_posts at all.

First, create your custom page template. I assume you’ve already done this.

Second, you need to create a custom query, using WP_Query():

global $post;
$types = $post->post_name;

$trips_query_args = array( 
    'post_type' => 'trips', 
    'types' => $types, 
);

$trips_query = new WP_Query( $trips_query_args );

(Note: what is the 'types' parameter? As far as I know, it’s not a core query parameter. Are you using it somehow?)

Third, we need to let WordPress know that it needs to base pagination on our custom query rather than on the default query:

global $wp_query;
// Put default query object in a temp variable
$tmp_query = $wp_query;
// Now wipe it out completely
$wp_query = null;
// Re-populate the global with our custom query
$wp_query = $trips_query;

At this point, we’ve moved the default query into a temporary variable, and re-populated the $wp_query global with our custom query.

Fourth, we need to output our custom query loop:

if ( $trips_query->have_posts() ) : while ( $trips_query->have_posts() ) : $trips_query->the_post();

    // Normal loop output goes here
    // You can use loop template tags normally
    // such as the_title() and the_content()

endwhile; endif;

Just put your loop output into the above. I’ve omitted it for brevity.

Fifth, we just need to reset things:

// Restore original query object
$wp_query = $tmp_query;
// Be kind; rewind
wp_reset_postdata();

This should be all you need to output a custom query loop, with proper pagination.

Edit

The use of taxonomy {slug} => {term} as a query taxonomy parameter was deprecated in WordPress 3.1, in favor of 'tax_query'. You should replace this:

'types' => $types

…with this:

'tax_query' => array(
    array(
        'taxonomy' => 'types',
        'field'    => 'slug',
        'term'     => $types
    ) 
)

This would make your $types_query_args array look like this:

$trips_query_args = array( 
    'post_type' => 'trips', 
    'tax_query' => array(
        array(
            'taxonomy' => 'types',
            'field'    => 'slug',
            'term'     => $types
        ) 
    )
);

Edit

@ChipBennett interesting development. I added ‘paged’ => N to the $trips_query_args array, where N stands for a number. When adding 1 the page actually shows exactly the perfect results for page 1. When adding 2 it shows the perfect results for page 2. However when using the navigation links OR even manipulating the URL, it no longer works. Any ideas?

So, let’s try forcing the query pagination, using the following:

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

You would update your $trips_query_args array accordingly:

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

$trips_query_args = array( 
    'post_type' => 'trips', 
    'tax_query' => array(
        array(
            'taxonomy' => 'types',
            'field'    => 'slug',
            'term'     => $types
        ) 
    ),
    'paged'    => $paged;
);

Does that result in correct pagination?

Leave a Comment