Ajaxifying Pagination on your WordPress Site

So I am currently converting a Drupal site to WordPress, and one of the features I had to build was ajax powered pagination. Now, WordPress does pagination pretty effectively already, but the ajax is all up to the theme developer.

Fortunately, I’d built the theme using WP 3.0’s new get_template_part() functionality to include one loop in all template pages. I didn’t realize how helpful that would be at the time, but I want to share it with you now. I develop themes and plugins using OOP 1, but I’ve only included the relevant parts. Also, the loop file is wrapped in a div with an id of content_container in the template files.

So here’s how I added this functionality in fewer than 50 lines of code (including javascript):

functions.php (25 lines):

class JPB_Theme  {
  function __construct(){
    add_action( 'wp_ajax_jpb_ajax_pagination', array( $this, 'ajax_pagination' ) );
    add_action( 'wp_ajax_nopriv_jpb_ajax_pagination', array( $this, 'ajax_pagination' ) );
    add_filter( 'get_pagenum_link', array( $this, 'link' ) );
  }
  function link( $in ){
    add_action( 'wp_footer', array( $this, 'footer' ) );
    return $in;
  }
  function footer( $in ){
    wp_register_script( 'jpb-pagination', get_stylesheet_directory_uri() . '/js/jpb.pagination.js', array('jquery'), '1.0' );
    wp_localize_script( 'jpb-pagination', 'JPB', array(
      'ajaxurl' => admin_url( 'admin-ajax.php' );
    ));
    wp_print_scripts( 'jpb-pagination' );
  }
  function ajax_pagination(){
    $filtered_data = array_map( 'esc_attr', $_POST );
    query_posts( $filtered_data );
    get_template_part( 'loop' );
    die();
  }
}
$JPB = new JPB_Theme();

js/jpb.pagination.js (12 lines):

jQuery(document).ready(function($){
  $('#pagination a').click(function(e){
    e.preventDefault();
    var data = {
      action : 'jpb_ajax_pagination'
    };
    data.paged = //page/d+/?$/i.test($(this).attr('href')) ? parseInt( $(this).attr('href').replace( //page/(d+)/?$/i, '$1' ) : 1;
    $.post( JPB.ajaxurl, data, function( text ){
      $('#content_container').empty().append( text );
    });
  });
});

Of course, this only works with pretty permalinks on. It would require at least one more line to account for both kinds of permalinks. Also, there’s more code involved in loop.php and the other template files; however, those already existed prior to ajaxification. I really didn’t have to make ANY modifications to the actual template files.

These snippets are fully GPL. Feel free to use them, modify them, or do whatever. Attribution welcome. 😀

Let me know what you think by leaving a comment!

Notes:

  1. Object Oriented Programming

Kansas boy transplanted to DC. English major transplanted to web development. Lover of things.