Search code examples
phpwordpresspaginationcustom-post-type

Main loop with custom post type added - paginate_links doesn't work well


I have such a piece of code

     <?php 
     global $wp_query;
     $args = array_merge( $wp_query->query_vars, array( 'post_type' => array( 'post', 'project') ) );
     $wp_query = new WP_Query( $args );
     if ( have_posts() ) : while ( have_posts() ) : the_post(); 
     ?>

after the loop i have

      <?php             
    $permalink_structure = get_option('permalink_structure');
    $format = empty( $permalink_structure ) ? '?paged=%#%' : 'page/%#%/';

            echo paginate_links( array(
                'base' => get_pagenum_link(1) .'%_%',               
                'format' => $format,
                'current' => max( 1, get_query_var('paged') ),
                'total' => $wp_query->max_num_pages,
                'prev_text'    => __('«'),
                'next_text'    => __('»'),
                'show_all'     => false,
                'mid_size'     => 2,
                'end_size'     => 1,
            ) );

    ?>

now the problem is that if I have 6 posts and 18 projects and 3 posts per page ... paginate_links will generate (6+18)/3 pages i.e. 8 pages ... so I click on 2 and go to page number 2 .. but when I click on 3 .. I get error 404. As if paginate_links generates the required amound of page links but only the links to 6/3 pages word .. like 1 and 2. Problem is for sure because of custom post type added but I can't understand where is that problem. What may be the problem?


Solution

  • It looks like you have to alter the "main query" (you are using a "sub query" inside the "main query") to include your custom post type, so your pagination links will work.

    You can try to alter the "main query" using the pre_get_posts hook

    add_action( 'pre_get_posts', 'my_pre_get_posts' );
    function my_pre_get_posts( $query ) {
        if($query->is_main_query() && $query->is_home()){ // <-- EDIT this condition to your needs
            $query->set( 'post_type', array( 'post','projects' ) );
        }
    }
    

    where you place this code into the functions.php file in your current theme directory.

    This assumes you are using the pagination on the frontpage, i.e.

     http://example.com/page/5
    

    We have the condition $query->is_home() to check if we are on the frontpage. If you are on a different page, you can alter this condition to your needs.

    ps: I think your way is not working because you are doing it in the theme file and that is "too late" to alter the scope of the pagination links.