Custom Post Type Archive Page: Set Posts Per Page, Paginate

I have a custom post type called video. Would like to paginate its archive page, showing only 3 posts on each page.

There is also a custom loop on the archive page that outputs all the video posts (for a thumbnail gallery).

Read More

This is the archive-video.php:

<?php while( have_posts() ) : the_post(); ?>
    MAIN LOOP...
<?php endwhile; wp_reset_query(); ?>

<?php next_posts_link(); previous_posts_link(); >

<?php $custom_loop = new WP_Query( array('post_type' => 'video', 'posts_per_page' => '-1' ) );
<?php while ( $custom_loop->have_posts() ) : $custom_loop->the_post(); ?>
    CUSTOM LOOP...
<?php endwhile; ?>

I’ve tried to set the posts_per_page to 3 using pre_get_posts (code here). The pagination would work perfectly, but the custom loop now outputs only 3 posts and not all the posts!

Anyone with a hard-coded/non-plugin solution? Have been googling to no avail… Any advice/help would be most appreciated!!!

Related posts

Leave a Reply

3 comments

  1. The code in the link you posted will (using pre_get_posts) will always change the number of posts_per_page to 3 if you are querying posts from that type. So a better solution would be to not use that code and simply above you code, before :

    <?php while( have_posts() ) : the_post(); ?>

    add:

    if ( get_query_var('paged') )
        $paged = get_query_var('paged');
    elseif ( get_query_var('page') )
        $paged = get_query_var('page');
    else
        $paged = 1;
    query_posts(array('post_type' => 'video', 'posts_per_page' => '3', 'paged' => $paged ));
    

    and this will only effect that query and not all queries of that post type.

    Update:

    the structure of your code should look like this:

    if ( get_query_var('paged') )
        $paged = get_query_var('paged');
    elseif ( get_query_var('page') )
        $paged = get_query_var('page');
    else
        $paged = 1;
    query_posts(array('post_type' => 'video', 'posts_per_page' => '3', 'paged' => $paged ));
    while( have_posts() ) : the_post(); 
        //MAIN LOOP...
    endwhile; wp_reset_query(); 
    
    next_posts_link(); previous_posts_link(); 
    
    $custom_loop = new WP_Query( array('post_type' => 'video', 'posts_per_page' => '-1' ) );
    while ( $custom_loop->have_posts() ) : $custom_loop->the_post();
        //CUSTOM LOOP...
    endwhile;
    wp_reset_query(); 
    
  2. I would use the pre_get_posts hook in your case and I would filter the main query. Add the following code to your functions.php

    add_action( 'pre_get_posts', function ( $query ) {
      if ( $query->is_post_type_archive( 'video' ) && $query->is_main_query() && ! is_admin() ) {
        $query->set( 'posts_per_page', 3 );
      }
    } );
    

    Hope this helps!