Isotope Paging

In a recent project I was working on an in store kiosk built with WordPress where we were using Isotope to layout an author’s posts which were automatically pulled from that authors Pinterest account. Because this was going to be on a large touch screen, we wanted to remove any scrolling from the interface. In order to remove scrolling, we leveraged the filter capability of isotope to create a paging experience.

I’m assuming for the sake of this post that you are already familiar with isotope and how to hook it up and how it works. If not, I encourage you to check out their website: http://isotope.metafizzy.co/. This post is to demonstrate how to page through an authors posts laid out with isotope instead of scrolling using the filter method. I have omitted the category filters that we built in to the page due to the complexity, but if there is any interest in that aspect, let me know and I can do a follow up post.

Step by Step

Getting Started

Define the variables we will use for the paging that will be added:

$num = 0; // post number
$page_num = 1; // starting page number
$items_per_page = 14; // how many posts per page?
$i = 0; // our counter

Create the isotope container:

echo '<section id="pins" class="content-posts isotope">';

Start the loop:

while ( have_posts() ) : the_post();

Alright, here’s where we are so far:

<?php

$num = 0; // post number
$page_num = 1; // starting page number
$items_per_page = 14; // how many posts per page?
$i = 0; // our counter

echo '<section id="pins" class="content-posts isotope">';

while ( have_posts() ) : the_post();

Get the Image

Now let’s get the post and see if there is an image. If not, we’ll check the post gallery and grab the first image in that. If there are no images there either, we will move on to the next post.

if(has_post_thumbnail( $post->ID )) {  
    $image = get_the_post_thumbnail($post->ID, 'medium'); //Get post thumbnail
} else if ($attachment) {
    $args = array( 'post_type' => 'attachment', 'numberposts' => 1, 'post_status' => null, 'post_parent' => $slide->ID );
    $attachment = get_posts($args);
    $image = wp_get_attachment_image($attachment[0]->ID, 'medium'); // or get post attachment if no thumbnail
} else {
    $image = false; // return false if there are no images
}

if (!$image) continue; // next item if no image is found

Create a container for the image and add the page number in ‘page’:

echo '<article class="post pin isotope-item" page="'.$page_num.'">'.$image.'</article>'; // add post item

Increase the post count:

$num++;

Here’s what that all looks like:

if(has_post_thumbnail( $post->ID )) {  
    $image = get_the_post_thumbnail($post->ID, 'medium'); //Get post thumbnail
} else if ($attachment) {
    $args = array( 'post_type' => 'attachment', 'numberposts' => 1, 'post_status' => null, 'post_parent' => $slide->ID );
    $attachment = get_posts($args);
    $image = wp_get_attachment_image($attachment[0]->ID, 'medium'); // or get post attachment if no thumbnail
} else {
    $image = false; // return false if there are no images
}

if (!$image) continue; // next item if no image is found

echo '<article class="post pin isotope-item" page="'.$page_num.'">'.$image.'</article>'; // add post item


//add page numbers for all categories

$num++; // increase post number

Add the Paging Buttons

Add a check to see if there are the correct number of posts on this “page”:

if (!($num % $items_per_page)){

If there are, make sure we are not on page 1 and add the page buttons:

if ($page_num > 1) {

    //next page
    echo '<article class="goto-page next post isotope-item" page="'.($page_num-1).'">'. //show on previous page
    '<a href="#" class="page" page="article.post[page~='.($page_num).']">'. //point to this page
    '<span>More Styles</span></a></article>';

    //previous page
    echo '<article class="goto-page previous post isotope-item" page="'.$page_num.'">'. //show on previous page
    '<a href="#" class="page" page="article.post[page~='.($page_num-1).']">'. //point to this page
    '<span>Previous Styles</span></a></article>';

}

Increase the page number and close the expression:

    $page_num++; // increase the page number
}

This is our progress so far:

<?php

$num = 0; // post number
$page_num = 1; // starting page number
$items_per_page = 14; // how many posts per page?
$i = 0; // our counter

echo '<section id="pins" class="content-posts isotope">';

while ( have_posts() ) : the_post();

    if(has_post_thumbnail( $post->ID )) {  
        $image = get_the_post_thumbnail($post->ID, 'medium'); //Get post thumbnail
    } else if ($attachment) {
        $args = array( 'post_type' => 'attachment', 'numberposts' => 1, 'post_status' => null, 'post_parent' => $slide->ID );
        $attachment = get_posts($args);
        $image = wp_get_attachment_image($attachment[0]->ID, 'medium'); // or get post attachment if no thumbnail
    } else {
        $image = false; // return false if there are no images
    }

    if (!$image) continue; // next item if no image is found

    echo '<article class="post pin isotope-item" page="'.$page_num.'">'.$image.'</article>'; // add post item


    //add page numbers for all categories

    $num++; // increase post number

    if (!($num % $items_per_page)){ // if the page is full, add page button and move to next page
        if ($page_num > 1) {

            //next page
            echo '<article class="goto-page next post isotope-item" page="'.($page_num-1).'">'. //show on previous page
            '<a href="#" class="page" page="article.post[page~='.($page_num).']">'. //point to this page
            '<span>More Styles</span></a></article>';

            //previous page
            echo '<article class="goto-page previous post isotope-item" page="'.$page_num.'">'. //show on previous page
            '<a href="#" class="page" page="article.post[page~='.($page_num-1).']">'. //point to this page
            '<span>Previous Styles</span></a></article>';

        }

        $page_num++; // increase the page number

    }

Closing it Up

Close the While:

endwhile;

Now we need to do one final check. If the last page is only partially full, it won’t have any links going to it. So let’s check to see if the last page is full and if not, well create some links.

// if the last page is not full, add page button
if ( $page_num > 1 && ($num % $items_per_page) != 0 ){
    //next page
    echo '<article class="goto-page next post isotope-item" page="'.($page_num-1).'">'. //show on previous page
    '<a href="#" class="page" page="article.post[page~='.($page_num).']">'. //point to this page
    '<span>More Styles</span></a></article>';

    //previous page
    echo '<article class="goto-page previous post isotope-item" page="'.$page_num.'">'. //show on previous page
    '<a href="#" class="page" page="article.post[page~='.($page_num-1).']">'. //point to this page
    '<span>Previous Styles</span></a></article>';
}

Finally, close out the container:

echo '</section>';

Here is the complete PHP

<?php

$num = 0; // post number
$page_num = 1; // starting page number
$items_per_page = 14; // how many posts per page?
$i = 0; // our counter

echo '<section id="pins" class="content-posts isotope">';

while ( have_posts() ) : the_post();

    if(has_post_thumbnail( $post->ID )) {  
        $image = get_the_post_thumbnail($post->ID, 'medium'); //Get post thumbnail
    } else if ($attachment) {
        $args = array( 'post_type' => 'attachment', 'numberposts' => 1, 'post_status' => null, 'post_parent' => $slide->ID );
        $attachment = get_posts($args);
        $image = wp_get_attachment_image($attachment[0]->ID, 'medium'); // or get post attachment if no thumbnail
    } else {
        $image = false; // return false if there are no images
    }

    if (!$image) continue; // next item if no image is found

    echo '<article class="post pin isotope-item" page="'.$page_num.'">'.$image.'</article>'; // add post item


    //add page numbers for all categories

    $num++; // increase post number

    if (!($num % $items_per_page)){ // if the page is full, add page button and move to next page
        if ($page_num > 1) {

            //next page
            echo '<article class="goto-page next post isotope-item" page="'.($page_num-1).'">'. //show on previous page
            '<a href="#" class="page" page="article.post[page~='.($page_num).']">'. //point to this page
            '<span>More Styles</span></a></article>';

            //previous page
            echo '<article class="goto-page previous post isotope-item" page="'.$page_num.'">'. //show on previous page
            '<a href="#" class="page" page="article.post[page~='.($page_num-1).']">'. //point to this page
            '<span>Previous Styles</span></a></article>';

        }

        $page_num++; // increase the page number

    }

endwhile;

// if the last page is not full, add page button
if ( $page_num > 1 && ($num % $items_per_page) != 0 ){
    //next page
    echo '<article class="goto-page next post isotope-item" page="'.($page_num-1).'">'. //show on previous page
    '<a href="#" class="page" page="article.post[page~='.($page_num).']">'. //point to this page
    '<span>More Styles</span></a></article>';

    //previous page
    echo '<article class="goto-page previous post isotope-item" page="'.$page_num.'">'. //show on previous page
    '<a href="#" class="page" page="article.post[page~='.($page_num-1).']">'. //point to this page
    '<span>Previous Styles</span></a></article>';
}
echo '</section>';

?>

The JavaScript

Again, I’m assuming that you are already familiar with isotope, so I’m just going to past my code and I trust you will know what it means.

(function ($) {
    var container = $('section.content-posts');

    container.isotope( { itemSelector : 'article.post' } ); // specify container

    container.isotope( { filter : "article.post[page~='1']" } ); // starting filter
   
    $('article.goto-page a').click(function(){
        var selector = $(this).attr('page'); // make selector equal to the value we put in 'page'

        container.isotope( { filter : selector });
        return false;
    })         
} )(jQuery);

That’s it! I hope this helps you with your projects. If you have any questions or want me to go over anything in more detail, feel free to leave a comment.

16 comments

  1. Paul says:

    Thanks, I was looking for paging with Isotope and I’m very interrested in the combination with category-filtering in Javascript.

    • Me says:

      Glad to hear it! Let me know if you have any questions. I put this up mainly to build out my portfolio not necessarily to be followed as a tutorial. I didn’t actually think anyone else would try and do this. 🙂

    • Me says:

      Yes! Actually, in the application that I built, I had one set of filters for the paging and another set for categories. The paging is really just a filter and, as far as I’m aware, you can add any number of filters to isotope and can separate them with data- tags.

      • abiwab says:

        Hi !
        Thanks a lot for your code, it works like a charm ! However I’d also like to add some other filters, but I really don’t know how to merge your code with the one given by Isotope.

        On the Isotope website they give this code :

        // store filter for each group
        var filters = {};

        $demo.on( 'click', '.button', function() {
          var $this = $(this);

          var $buttonGroup = $this.parents('.button-group');
          var filterGroup = $buttonGroup.attr('data-filter-group');

          filters[ filterGroup ] = $this.attr('data-filter');

          var filterValue = '';
          for ( var prop in filters ) {
            filterValue += filters[ prop ];
          }

          $container.isotope({ filter: filterValue });
        });

        Could you please help me merge these codes so that I can add other filters ?

        Thanks a lot ! 😉

        • Tanner says:

          So, this actually is where this system gets pretty complicated. The trick is to create a new paging data attribute for each filter you want to add AND a set of paging buttons for each filter also. These paging buttons should also have the appropriate data attributes on them so they only show when a filter is active. Also note that you will need to re-calculate the paging numbers for each of these filters, do not use the same page numbers you are using for the general paging.

          The link for these new filter paging buttons should be constructed something like:

          /**
           * Set the page attribute to filter our custom filter + filter page number instead of just the page number
           * where filter_page_num is the target page number for this filter specifically
           **/
          <a href="#" class="page" page="article.post[filter~=filter_[filter_page_num]_page]"><span>More Styles</span></a>'

          I hope that helps! I am planning on extending this tutorial sometime to include this advanced feature but haven’t yet.

  2. aleksander says:

    oh!! it was real problem for me with isotope pagination. real thx for you man!!!! I was looking for paging with Isotope! thx!!!

  3. Silvana says:

    I´m principiant in isotope and I´need the pagination and filter, can you send me a completed example ??
    Excusame for my english!!
    Thanks!!

    • Tanner says:

      Hey Silvana! Unfortunately this code was part of an internal application and does not exist anywhere in public (although I have thought of creating a demo). Do you have any specific questions I can help with?

  4. Silvana says:

    I’m really doesn`t works in WP, I have php application with a isotope gallery but I have one hundred element to show because is neccesary paging. Do you have any example for me?.

  5. Miles says:

    This is exactly what I needed! One thing I had to change was:

    if ($page_num > 1) {

    to

    if ($page_num > 0) {

    Otherwise it wouldn’t add in the page navigation to the first page.

    I also added “if ($page_num > 1) :” before and “endif;” after the previous page button code to prevent it from showing up on the first page. The second set of buttons didn’t seem to work for me, they were being displayed no matter what the page.

    Thanks for taking the time to put this post together, much appreciated!

  6. Zaida says:

    Hello,
    Thank you very much for sharing this. I’m using isotope with filters and I need pagination but I’m having problems setting it up. Previously I wanted to use wp_paginavi but it didn’t work (its code is still in)
    I show you my code if you can help me to achieve pagination.

    Edited for brevity

    Thank you very much in advance. Any advice is helpful
    Zaida

    • tanner says:

      Hey Zaida! I looked at your code but did not see any easy fixes (partially because it didn’t copy over very cleanly). Did you get the filters to work? If so think of paging more like an extra filter. So add a data-page attributes to your items and create another set of filters for the pages. Then, just make sure to initialize the extra filter in the js. See this example for multiple filters: http://isotope.metafizzy.co/v1/demos/combination-filters.html.

Leave a Reply