Made of Everything You're Not

Professional(?!?!) blog of Eric Lamb.
  • Home
  • Projects
  • Portfolio
  • Resume
« WP-Click-Tracker 0.3
Video Mobile Blogging »

Worpress Style Pagination

I’ve been working on a new code base for StreetWise these past couple months, getting ready for the upcoming busy season, and as this new code needs to support membership of 1,000,000+ people decided I wanted, no, needed, to rework my pagination algorithm.

The Problem

Previously, I’ve gone for a basic approach of just listing out the links sequentially with a Next and Prev state. For larger page sets, I would just remove the numeric links. For example they would look like the below:

1 2 3 4 5 etc…

This becomes problematic at higher numbers though; just imagine the page would look if there were 1,000 pages instead of five. Here’s an example of just 100:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100

So it can be a bit of a problem.

The Replacement

A lot of websites are using a better pagination style that’s sometimes called WordPress pagination. This pagination style presents only a few links at a time while still allowing more freedom than the basic Next Prev style. Here’s an example:

« Previous 1 2 3 … 10 11 12 13 14 … 118 119 120 Next »

The Solution

Being it’s called WordPress pagination, and that I’m a lazy php programmer, I just stole the code from WordPress and translated it into something a little more portable.

function paginate_links($format = '?page=%#%', $total = '1', $current = '0', $base = '%_%', $show_all = FALSE, $prev_next = TRUE, $prev_text = '« Previous', $next_text = 'Next »',$end_size = '3',$mid_size = '2',$type = 'plain') {
 
	$total = (int) $total;
	if($total < 2) {
		return;
	}
	$current  = (int) $current;
	$end_size = 0  < (int) $end_size ? (int) $end_size : 1; // Out of bounds?  Make it the default.
	$mid_size = 0 <= (int) $mid_size ? (int) $mid_size : 2;
	$r = '';
	$page_links = array();
	$n = 0;
	$dots = false;
 
	if ( $prev_next && $current && 1 < $current ){
		$link = str_replace('%_%', 2 == $current ? '' : $format, $base);
		$link = str_replace('%#%', $current - 1, $link);
		$link .= $add_fragment;
		$page_links[] = "<a class='prev page-numbers' href='" . clean_url($link) . "'>$prev_text</a>";
	}
 
	for ( $n = 1; $n <= $total; $n++ ) {
		$n_display = number_format($n);
		if ( $n == $current ) {
			$page_links[] = "<span class='page-numbers current'>$n_display</span>";
			$dots = true;
		} else {
			if ( $show_all || ( $n <= $end_size || ( $current && $n >= $current - $mid_size && $n <= $current + $mid_size ) || $n > $total - $end_size ) ) {
				$link = str_replace('%_%', 1 == $n ? $format : $format, $base);
				$link = str_replace('%#%', $n, $link);
				$link .= $add_fragment;
				$page_links[] = "<a class='page-numbers' href='" . clean_url($link) . "'>$n_display</a>";
				$dots = true;
			} elseif ( $dots && !$show_all ) {
				$page_links[] = "<span class='page-numbers dots'>...</span>";
				$dots = false;
			}
		}
	}
 
	if ( $prev_next && $current && ( $current < $total || -1 == $total ) ) {
		$link = str_replace('%_%', $format, $base);
		$link = str_replace('%#%', $current + 1, $link);
		$link .= $add_fragment;
		$page_links[] = "<a class='next page-numbers' href='" . clean_url($link) . "'>$next_text</a>";
	}
 
	switch ( $type ) {
		case 'array' :
			return $page_links;
			break;
		case 'list' :
			$r .= "<ul class='page-numbers'>\n\t<li>";
			$r .= join("</li>\n\t<li>", $page_links);
			$r .= "</li>\n</ul>\n";
			break;
		default :
			$r = join("\n", $page_links);
			break;
	}
 
	return $r;
}

As you can see, especially if you’re already familiar with WordPress, all I’ve done is take out the WordPress specific functions and set the $args to function parameters. Pure theft :)

There are a bunch of paramaters and options you can configure the links by but only the first 3 are really needed to make the function work.

Here’s an example:

$numofpages = 20;
$page = '4'
$query_string = 'foo='.$foo.'&bar='.$bar;
echo paginate_links('?'.$query_string.'&page=%#%', $numofpages, $page);

I didn’t put too much work into this, which is kinda the point, but I hope it’s helpful!

Bookmark and Share

Related Posts

Stand Alone ExpressionEngine Authentication
Importing Legacy Users Into ExpressionEngine
CartThrob 2.0 Beta Fun
ExpressionEngine and the Mystery of M00o93H7pQ09L8X1t49cHY01Z5j4TT91fGfr
Custom Routes With Zend Framework

Tags: pagination, php, wordpress

This entry was written by Eric Lamb and posted on Monday, February 2nd, 2009 at 11:12 pm and is filed under Code, Programming. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply

Click here to cancel reply.

  • Subscribe: Entries | Comments
  • About Me

    Email Email
    Twitter Twitter
    310.739.3322
  • Categories

    • Brain Dump
    • Business
    • Code
    • IT
    • Programming
    • Rant
    • Servers
  • Archives

    • October 2011
    • August 2011
    • July 2011
    • June 2011
    • May 2011
    • April 2011
    • March 2011
    • February 2011
    • January 2011
    • December 2010
    • November 2010
    • October 2010
    • September 2010
    • August 2010
    • July 2010
    • June 2010
    • May 2010
    • April 2010
    • March 2010
    • February 2010
    • January 2010
    • December 2009
    • November 2009
    • October 2009
    • September 2009
    • August 2009
    • July 2009
    • June 2009
    • May 2009
    • April 2009
    • March 2009
    • February 2009
    • January 2009
    • December 2008
    • November 2008
    • October 2008

Copyright © 2008 - 2012 Eric Lamb - All rights reserved