Dejo Dekic
Dejo Dekic

Reputation: 2126

How to create separate pagination for mutiple loops?

I have created two loops with pagination (first loop loops through CAT'S category and second loops through DOG'S category), but now I am stuck:(

The problem: After I click "Next entry" on my site (CAT'S category) it goes to second entry in that category BUT it also goes to my DOG'S category second entry (I don't want THAT!! ). It also happens vice versa...

What I like to do is this: I click on "Next Entry" on my CAT'S category and it goes only to next post in THAT category (CAT'S) but NOT to second post in my DOG'S category, or another way around: I click on "Next Entry" on my DOG'S category and it goes only to next post in THAT category (DOG'S) but NOT to second post in my CAT'S category .

Can someone help me please? I have asked for help on wordpress.stackexchange.com a while ago but I didn't get any answer so I am asking question here.

Index php looks like this:

<?php get_header(); ?>
<?php get_sidebar(); ?>
<div id="blog">         
    <?php         
    $args = array(
    'category_name' => 'cats' 
    );
    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    $the_query = new WP_query($args . '&paged=' . $paged . '&cat=-3');      
    while( $the_query -> have_posts()) : $the_query -> the_post();              
    ?>

    <div class="post">
    <div class="post_title">
    <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
    </div>
        <div class="entry"> 
            <?php the_post_thumbnail(); ?>
            <?php the_content('Read on...'); ?>

            <p class="postmetadata">
            <?php _e('Filed under&#58;'); ?> <?php the_category(', ') ?> <?php _e('by'); ?> <?php  the_author(); ?><br />
            <?php comments_popup_link('No Comments &#187;', '1 Comment &#187;', '% Comments &#187;'); ?> <?php edit_post_link('Edit', ' &#124; ', ''); ?>
            </p>
        </div>
    </div>

    <?php endwhile;?>
    <?php wp_reset_postdata();?>
    <div class="navigation">
    <div style="float:left;" class="alignleft"><?php previous_posts_link('&laquo; Previous Entries') ?></div>
    <div style="float:right;" class="alignright"><?php next_posts_link('Next Entries &raquo;',$the_query->max_num_pages) ?></div>
    </div>      
    </div>

    <div id="blogs">    
    <?php       
    $args = array(
    'category_name' => 'dogs' 
    );
    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    $the_query = new WP_query($args . '&paged=' . $paged . '&cat=-10');
    while( $the_query -> have_posts()) : $the_query -> the_post();              
    ?>

    <div class="post">
    <div class="post_title">
    <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
    </div>
        <div class="entry"> 
            <?php the_post_thumbnail(); ?>
            <?php the_content('Read on...'); ?>

            <p class="postmetadata">
            <?php _e('Filed under&#58;'); ?> <?php the_category(', ') ?> <?php _e('by'); ?> <?php  the_author(); ?><br />
            <?php comments_popup_link('No Comments &#187;', '1 Comment &#187;', '% Comments &#187;'); ?> <?php edit_post_link('Edit', ' &#124; ', ''); ?>
            </p>

        </div>
    </div>

    <?php endwhile;?>
    <?php wp_reset_postdata();?>
    <div class="navigation">
    <div style="float:left;" class="alignleft"><?php previous_posts_link('&laquo; Previous Entries') ?></div>
    <div style="float:right;" class="alignright"><?php next_posts_link('Next Entries &raquo;',$the_query->max_num_pages) ?></div>
    </div>
    </div>
   <?php get_footer(); ?>

Upvotes: 3

Views: 1900

Answers (4)

Tom
Tom

Reputation: 1366

You need 2 different paging values so add some new ones and rewrite rules which look for them (they're really just to make the urls neater looking). The rewrite rules and the pagination link format mean you can page through one category while the other category page doesn't change.

In functions.php:

function add_new_rules()
{
  // new 'paged' variables
  global $wp;
  $wp->add_query_var('paged_cats');
  $wp->add_query_var('paged_dogs');

  // rewrite rules
  add_rewrite_rule('page/cats/(\d+)/dogs/(\d+)', 'index.php?paged_cats=$matches[1]&paged_dogs=$matches[2]', 'top');
  add_rewrite_rule('page/cats/(\d+)/dogs/?$', 'index.php?paged_cats=$matches[1]&paged_dogs=1', 'top');

  if( !array_key_exists('page/cats/(\d+)/dogs/(\d+)', (array)get_option('rewrite_rules')) )
  {
    global $wp_rewrite;
    $wp_rewrite->flush_rules();
  }
}
add_filter('init', 'add_new_rules');

Check for the new query vars in index.php and use them for each WP_Query and the related pagination links.

<div id="blog">
  <?php
  $paged_cats = (get_query_var('paged_cats')) ? get_query_var('paged_cats') : 1;
  $paged_dogs = (get_query_var('paged_dogs')) ? get_query_var('paged_dogs') : 1;

  $cats = new WP_query(array(
    'category_name' => 'cats',
    'paged' => $paged_cats,
    'posts_per_page' => 1
  ));
  while( $cats->have_posts() ) : $cats->the_post();
    ?>
    <div class="post">
      <div class="post_title">
        <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
      </div>
      <div class="entry">
        <?php the_post_thumbnail(); ?>
        <?php the_content('Read on...'); ?>
        <p class="postmetadata">
          <?php _e('Filed under&#58;'); ?> <?php the_category(', ') ?> <?php _e('by'); ?> <?php the_author(); ?><br />
          <?php comments_popup_link('No Comments &#187;', '1 Comment &#187;', '% Comments &#187;'); ?> <?php edit_post_link('Edit', ' &#124; ', ''); ?>
        </p>
      </div>
    </div>
  <?php endwhile; ?>
  <?php wp_reset_postdata(); ?>
  <?php if ( $cats->max_num_pages > 1 ) : ?>
  <div class="navigation">
    <?php
    echo paginate_links(array(
      'base' => home_url("page/cats/%#%/dogs/{$paged_dogs}"),
      'format' => '%#%',
      'current' => $paged_cats,
      'total' => $cats->max_num_pages,
    ));
    ?>
  </div>
  <?php endif; ?>
</div>

  <hr>

<div id="blogs">
  <?php
  $dogs = new WP_query(array(
    'category_name' => 'dogs',
    'paged' => $paged_dogs,
    'posts_per_page' => 1
  ));
  while( $dogs->have_posts() ) : $dogs->the_post();
    ?>
    <div class="post">
      <div class="post_title">
        <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
      </div>
      <div class="entry">
        <?php the_post_thumbnail(); ?>
        <?php the_content('Read on...'); ?>
        <p class="postmetadata">
          <?php _e('Filed under&#58;'); ?> <?php the_category(', ') ?> <?php _e('by'); ?> <?php  the_author(); ?><br />
          <?php comments_popup_link('No Comments &#187;', '1 Comment &#187;', '% Comments &#187;'); ?> <?php edit_post_link('Edit', ' &#124; ', ''); ?>
        </p>
      </div>
    </div>
  <?php endwhile;?>
  <?php wp_reset_postdata();?>
  <?php if ( $dogs->max_num_pages > 1 ) : ?>
  <div class="navigation">
    <?php
    echo paginate_links(array(
      'base' => home_url("page/cats/{$paged_cats}/dogs/%_%"),
      'format' => '%#%',
      'current' => $paged_dogs,
      'total' => $dogs->max_num_pages,
    ));
    ?>
  </div>
  <?php endif; ?>
</div>

Upvotes: 2

jho1086
jho1086

Reputation: 2128

I find answer here https://wordpress.stackexchange.com/questions/47259/multiple-wp-query-loops-with-pagination, the choice answer is working with me. It use format.

<!-- Cats -->
<div class="animals">
    <?php
        $paged1 = isset( $_GET['paged1'] ) ? (int) $_GET['paged1'] : 1;
        $paged2 = isset( $_GET['paged2'] ) ? (int) $_GET['paged2'] : 1;

        // Custom Loop with Pagination 1
        // http://codex.wordpress.org/Class_Reference/WP_Query#Usage
        $args1 = array(
            'paged'          => $paged1,
            'posts_per_page' => 2,
        );
        $query1 = new WP_Query( $args1 );

        while ( $query1->have_posts() ) : $query1->the_post();
            the_title();
            echo '<br>';
            the_category(' ');
            the_excerpt();
            echo '<hr>';
        endwhile;

        // http://codex.wordpress.org/Class_Reference/WP_Query#Pagination_Parameters
        $pag_args1 = array(
            'format'  => '?paged1=%#%',
            'current' => $paged1,
            'total'   => $query1->max_num_pages,
            'add_args' => array( 'paged2' => $paged2 )
        );
        echo paginate_links( $pag_args1 );
    ?>
</div>

<!-- Dogs -->
<div class="animals">
    <?php
        // Custom Loop with Pagination 2
        $args2 = array(
            'paged'          => $paged2,
            'posts_per_page' => 2,
        );
        $query2 = new WP_Query( $args2 );

        while ( $query2->have_posts() ) : $query2->the_post();
            the_title();
            echo '<br>';
            the_category(' ');
            the_excerpt();
            echo '<hr>';
        endwhile;

        $pag_args2 = array(
            'format'  => '?paged2=%#%',
            'current' => $paged2,
            'total'   => $query2->max_num_pages,
            'add_args' => array( 'paged1' => $paged1 )
        );
        echo paginate_links( $pag_args2 );
    ?>
</div>

And since it is generating a un-clean url you can add a rel="nofollow" for SEO purposes. Here is the instruction how to do add rel="nofollow"

Upvotes: 1

Farrukh Subhani
Farrukh Subhani

Reputation: 2038

Your problem is this: On pagination wordpress sends page id or count to get the next enteries and the name of the variable that goes in postback is same for both lists. When it goes to the server both lists get a request to go to next page by looking at the post variables.

The solution mentioned by jho1086 is to create paged variable as a custom variable for both lists and assign it. this would then send a different variable for each list and you can move next or previous as you wish.

You need to do both add a paged variable and add it to your pagination as well. In jho1086's solutuin see $args1 and $pag_args1 both have reference to $paged2 to make this happen.

  • When you select page 2 for cats it should send a catpage=2 to the server
  • When you select page 2 for Docs it should send a dogpage=2 to the server

If you can solve this for pagination links and pass the args then you can do following

  • When server gets the list of cats use catpage as a paging param
  • When server gets the list of dogs use dogpage as a paging param

This is in theory and will surely work. You can test variables going in and out of the request via firebug and comeback with what other issues you have but the reason your loops go to page 2 for clicking on one is that both loops are paging on the same post variable.

Upvotes: 1

Obmerk Kronen
Obmerk Kronen

Reputation: 15969

the functions next_post_link() and previous_post_link() has a third argument called 'in_same_cat' - You will need to set it to TRUE. Read the codex page (click on the functions name in the answer .

From codex :

<?php next_post_link('%link', 'Next post in category', TRUE); ?>

They even have a fourth argument 'excluded_categories' which you can also use for achieving the same thing, or combining both to get even more sophisticated results.

Upvotes: 0

Related Questions