How To Set Up Numbered Page Navigation In Thesis

One of the most annoying things about most WordPress themes, even an advanced one like Thesis, is the navigation system for blog, archive, and search pages. Typically, all you get at the bottom of a blog’s homepage is two links. One is for “newer posts” and one is for “older posts” or something similar. This is not exactly optimal. Fortunately, its possible to replace this native functionality with numbered page navigation.

What is Numbered Page Navigation?

Numbered page navigation is simply a list of links to a range of pages within a few pages of the page you are currently viewing. This list appears at the bottom of any area of your blog with multiple posts numbering greater than the amount of posts your blog is set to display on one page (this can be changed under the “Reading” options under the “Settings” tab in your WP admin). Your visitors will then be able to choose to visit any number of pages from one page rather than scrolling through them one at a time to find the desired page.

numnav

How Can I Setup Numbered Page Navigation On My Blog?

There are two ways you can do this. If you want to be boring, you can use a plugin called WP Pagenavi. Its actually a really nice plugin and I would recommend it if you don’t want to get your hands dirty.

However, as your blog grows, you’ll find yourself wanting to change things, add new features, etc. As this happens, you’ll find yourself using more and more plugins. The more plugins you use, the slower your blog will be. I don’t know about you, but I’m all about keeping my blog clean and fast, so I make every attempt to avoid plugins when I can.

The code we’ll be using to create our numbered page nav is actually based on the same code that WP Pagenavi utilizes. However, I’ve tailored it to a blogger’s needs and cleaned it up a bit to make this as painless as possible for the coding impaired. I know it looks like a lot to swallow, but don’t worry. I’ll walk you through it.

In order to work properly, we need to write a typical wordpress function. Then, we’ll call that function using a Thesis hook to place it directly below the last post on each page where page navigation is displayed. Finally, we’ll add CSS customizations to make it look good. It will take a bit of coding knowledge to understand what’s going on here, but if you can copy and paste, you can implement this!

The Code

function numbered_page_nav($prelabel = '', $nxtlabel = '', $pages_to_show = 8, $always_show = false) {
	global $request, $posts_per_page, $wpdb, $paged;

	$custom_range = round($pages_to_show/2);
	if (!is_single()) {
		if(!is_category()) {
			preg_match('#FROM\s(.*)\sORDER BY#siU', $request, $matches);
		}
		else {
			preg_match('#FROM\s(.*)\sGROUP BY#siU', $request, $matches);
		}
		$blog_post_count = $matches[1];
		$numposts = $wpdb->get_var("SELECT COUNT(DISTINCT ID) FROM $blog_post_count");
		$max_page = ceil($numposts /$posts_per_page);
		if(empty($paged)) {
			$paged = 1;
		}
		if($max_page > 1 || $always_show) {
			echo "<div class='page-nav'><div class='page-nav-intro'>Page $paged of $max_page</div>";
			if ($paged >= ($pages_to_show-2)) {
				echo '<div class="page-number"><a href="'.get_pagenum_link().'">1</a></div><div class="elipses">...</div>';
			}
			for($i = $paged - $custom_range; $i <= $paged + $custom_range; $i++) {
				if ($i >= 1 && $i <= $max_page) {
					if($i == $paged) {
						echo "<div class='current-page-number'>$i</div>";
					}
					else {
						echo '<div class="page-number"><a href="'.get_pagenum_link($i).'">'.$i.'</a></div>';
					}
				}
			}
			if (($paged+$custom_range) < ($max_page)) {
				echo '<div class="elipses">...</div><div class="page-number"><a href="'.get_pagenum_link($max_page).'">'.$max_page.'</a></div>';
			}
			echo "</div>";
		}
	}
}
remove_action('thesis_hook_after_content', 'thesis_post_navigation');
add_action('thesis_hook_after_content', 'numbered_page_nav');

The Breakdown

Worried? Don’t be. Its bark is worse than its bite. Let’s break it down piece by piece.

1. Setting the Parameters
function numbered_page_nav($prelabel = '', $nxtlabel = '', $pages_to_show = 8, $always_show = false) {
	global $request, $posts_per_page, $wpdb, $paged;
	$custom_range = round($pages_to_show/2);
	if (!is_single()) {
		if(!is_category()) {
			preg_match('#FROM\s(.*)\sORDER BY#siU', $request, $matches);
		}
		else {
			preg_match('#FROM\s(.*)\sGROUP BY#siU', $request, $matches);
		}

This section of code establishes the parameters of our function such as what WordPress elements we need, how many posts will be in our list, and which areas of your blog will need the navigation.

The main thing you need to understand here is that “$pages_to_show = 8″ simply means we’re going to list 8 pages other than the current page we’re on. You can change “8″ to whatever number you please. I’d strongly suggest that you use an even number as that will keep an equal number of pages on either side of the current page in our list.

2. How Big is Your Blog?
$blog_post_count = $matches[1];
$numposts = $wpdb->get_var("SELECT COUNT(DISTINCT ID) FROM $blog_post_count");
$max_page = ceil($numposts /$posts_per_page);
if(empty($paged)) {
	$paged = 1;
}

Next, we determine how many posts your blog contains, how many posts you allow on each page, and use those two pieces of information to determine how many pages will be in our display. It also states that nothing will be displayed if the page doesn’t contain enough posts to need multiple pages in order to display all posts.

3. Where are We?
if($max_page > 1 || $always_show) {
	echo "<div class='page-nav'><div class='page-nav-intro'>Page $paged of $max_page</div>";
	if ($paged >= ($pages_to_show-2)) {
		echo '<div class="page-number"><a href="'.get_pagenum_link().'">1</a></div><div class="elipses">...</div> ';
	}

The next section contains the code that displays our navigation intro box that tells us which page we’re on and how many total pages there are. It also contains the code that displays the first page link once we move far enough from the first page that its not natively displayed in the list.

4. The Meat
for($i = $paged - $custom_range; $i <= $paged + $custom_range; $i++) {
	if ($i >= 1 && $i <= $max_page) {
		if($i == $paged) {
			echo "<div class='current-page-number'>$i</div>";
		}
		else {
			echo ' <div class="page-number"><a href="'.get_pagenum_link($i).'">'.$i.'</a></div> ';
		}
	}
}

This section is a bit complicated, but it basically just lists the number of pages that are to be displayed. Remember when we set that up in the parameters? It also sets up a seperate class for the current page. That way you can style it differently if that suits your fancy.

5. The End
if (($paged+$custom_range) < ($max_page)) {
	echo ' <div class="elipses">...</div><div class="page-number"><a href="'.get_pagenum_link($max_page).'">'.$max_page.'</a></div>';
}
echo "</div>";

Finally, if the last page does not appear in our list natively, we include a link to it at the end.

6. Thesis Implementation
remove_action('thesis_hook_after_content', 'thesis_post_navigation');
add_action('thesis_hook_after_content', 'numbered_page_nav');

This is the easy part. You just need two lines of code (yep, Thesis rocks!). “thesis_hook_after_content” is the hook we’ll be using. It simply means that the numbered page nav will be placed below the end of the last post on the page. First, we remove the standard Thesis page navigation. Then, we add our custom function. If you wanted to place it below all content (posts and sidebars), but above the footer, you would use the “thesis_hook_after_content_box” hook. “thesis_post_navigation” refers to the standard Thesis page navigation. “numbered_page_nav” just indicates the name of the function we want to place in our chosen location.

And that’s it. Just copy and paste the whole thing into your custom_functions.php file and we’re ready to style!

Styling the Navigation

Just copy and paste this into your custom.css file and you are all done. Of course, you’ll want make stylistic adjustments to match the look of your blog.

<code>/* NUMBERED PAGE NAV */
.page-nav { font-size: 1.35em; font-weight: bold; margin: 1em 0; padding: 0; overflow: hidden; }
.page-nav-intro { float: left; padding: .3em .5em; margin: 0 1em 1em 0; background: #efefef; border: .1em solid #ccc; }
.page-number { float: left; padding: .3em .5em; margin: 0 .2em; background: #fff; border: .1em solid #ccc;  }
.current-page-number { float: left; padding: .3em .5em; margin: 0 .2em; background: #efefef; border: .1em solid #ccc; }
.elipses { float: left; padding: .3em .2em; }</code>

Get Free Updates From Art Of Blog

Insider Updates

Sign up to receive insider tips only available to our email subscribers.

Written by Adam Baird

(photo by Katey Nicosia)

Adam is a Wordpress designer, Thesis specialist, and blogger from Indianapolis, Indiana. Check out his personal blog or follow him on Twitter for more Thesis tips.

Adam has written 13 posts for Art of Blog!

{ 61 comments… read them below or add one }

Khürt L Williams January 22, 2010

Interestingly I was just thinking about doing this on my Thesis blog.

Reply

Mary Jaksch January 23, 2010

This is a good, thorough post but pretty technical. I’m nervous of completely ballsing my blog up if I try this.

I think your blog will attract more readers if you don’t just aim at bloggers who are comfortable with coding. The masses you want to attract aren’t.

At the moment your tagline (which is great) doesn’t line up with your content.

Reply

Nick Reese January 23, 2010

Mary,

Thanks for the keen observation. I will work on getting some more basic content on here. I also sent you an email with regards to what you would like to see. Look forward to connecting.

Reply

Adam Baird January 24, 2010

This is a bit of a technical article, but I wouldn’t worry about messing up your theme.

If you back up your custom_functions.php file before you do anything, you can always just load the backup in the event that something goes wrong :)

Reply

Rich Cook January 24, 2010

I just pasted the code into my blog and it works great. It’ll look even better when I have more than 2 pages!

I do have a question – I’m working on setting up category pages so that certain posts appear on certain pages, according to their primary category (Daily Logs appear on the Daily Log page, etc.). I’m not there yet (still trying to figure that one out!) but was wondering if the page number code will work across all pages or if I have to add it to individual pages to make it work on each individual page/category?

Thanks!
Rich

Reply

Adam Baird January 25, 2010

Rich,

It should work for all category pages.

Adam

Reply

tsudo January 24, 2010

Excellent tutorial and the code worked like a charm. Thank you

Reply

Scott January 26, 2010

Awesome tutorial, worked like a charm!

Reply

Adam Baird January 26, 2010

Thanks…now if only I can figure out how to unravel complicated php scripts ;)

Reply

Scott January 27, 2010

There is a PHP script I’m hoping someone can figure out.. I posted it in the classified section of the Thesis forums. The developer was sloppy from what I understand. (I don’t write code) Trying to get a PHP app to be “included” as a custom page. The owner of the software is no help.

Reply

Mark V February 3, 2010

I tried this on my site, vannonphotography.com and it worked but I can’t seem to get the colors to change even though I enter custom values for them. Any ideas?

Thanks

Reply

Adam Baird February 3, 2010

Tough to say what the problem is without actually looking at the code on your site. Just try to make sure the css selectors you are using match up to the ones in the code.

Reply

Mark V February 3, 2010

Thanks for the tip. I’m using “numbered page nav” code on this site, verbatim, in my custom.css file. I can change the font size but the color just doesn’t want to change. :-(

Reply

Adam Baird February 3, 2010

Looking at your site I’m assuming you are referring to the background colors and not the links/text themselves?

Reply

Pitchers Hit Eighth February 7, 2010

I would like to use this on tag archive pages as well, but every time I add the !is_tag() switch in with the !is_category() line, the nav disappears from the entire site.

Help? TIA.

Reply

Adam Baird February 8, 2010

That line of code doesn’t affect where the code displays. The nav should already display on your tag pages unless you have some sort of code that causes a conflict. It does for me…

Reply

Pitchers Hit Eighth February 8, 2010

Seems logical that may be the case, since my custom_functions.php is admittedly a bit of a mess.

I get the page nav on index and category pages, but nothing on tag pages, as you can see here:

http://www.pitchershiteighth.com/tag/albert-pujols/

Realize it could be anything, but do you have any suggestions on a good place to start looking? :)

Thanks.

Reply

Pitchers Hit Eighth February 8, 2010

BTW, FWIW – I’m not seeing the numbered nav at the bottom of your tag archive pages either…

http://www.artofblog.com/tag/thesis/

Reply

Mark Stevens February 26, 2010

I’m having the same problem. It all works fine except on the tag archives. My site relies heavily on tags for navigation, so I’m going to have to remove the nav until someone (hopefully!) figures this out. Bummer.

Reply

Pitchers Hit Eighth February 26, 2010

Mark-

I got it to work on tag archives by changing this line:

if(!is_category()) {

to read this way:

if(!is_category() && !is_tag()) {

YMMV, but hopefully it will work for you too!

Reply

Mark Stevens February 26, 2010

Nope, that just made it crash. Dang, I sure wanted to use the page nav. Thanks for your help!

Mark Stevens February 11, 2010

Being code-challenged, I’ve had more than one custom_function tutorial cause my blog to implode… but this one rocks! Thank You!!!

Reply

Chris Stroud February 25, 2010

Thanks for this one too! Only took a few minutes to implement.

Reply

Michael Novido March 21, 2010

How can I do this for pages instead of posts?

Reply

Willie Jackson April 12, 2010

I’m a little disappointed with this tutorial…it only took me about seven seconds to implement this on my site—can you make it more difficult next time?

iKeed…thanks for pumping out these consistently high-quality tutorials! Is there any way to add a “next” and “previous” button to this?

Reply

Shahab khan April 14, 2010

Nice tutorial Nick. Your code worked brilliantly !!
Now i am going to delete the WP-Page navi plugin.

Reply

John April 26, 2010

doesn’t work for me with Thesis 1.7 and with 1.6 it would sporadically disappear for no apparent reason. When it disappeared the first time, I had to follow your instructions again to get it back. This was strange because I didn’t do anything that should have caused it to simply vanish. Shame because when it was there, it looked great. I’m heading off to get the plugin you recommended instead.

Reply

Meedo Taha May 12, 2010

Weird… Worked fine for me at meedosite.com
Besides some CSS tweaks, I used the Adam’s code verbatim.
Wordpress 2.9.2 / Thesis 1.7.

Reply

Meedo Taha April 28, 2010

Hi. Great tutorial. I set it up on my blog without a hitch. Question: I’d create a hover effect to make it consistent with my nav menu and more visually appealing. Any chance you could help out with the coding?

Reply

Adam April 28, 2010

If you have specific questions I’m definitely willing to help. For starters, a:hover {} for the specific element you want the hover effect on would be the css selector to use…

Reply

Meedo Taha May 12, 2010

Thanks… But I have very limited experience with CSS. Guess I’ll do some research and try that out. :)

Reply

series May 13, 2010

Hi Nick Sorry if i ask here a quetion but i think is very sinilar to this post ,so I want to put 20 post in the front page but thesis onliy allow to put 10 post ,how i can change this ,thks

Reply

Nick Reese May 14, 2010

Wordpress settings -> Reading -> Blog Pages to Show -> 20

Reply

mohdisa May 16, 2010

nice tutorial, thanks. :)

Reply

ad May 21, 2010

Do you have a hint what’s going wrong on my site?
when i click on the last page (page 80), i get the information that the page can’t be found.

Reply

Nick Reese May 21, 2010

Are you running any custom loops on the site?

Reply

ad May 21, 2010

Nope.

Strange – i’ve put the code in my second thesis installation at http://www.apfelquak.de and there it’s working fine.

Reply

Adam Baird May 21, 2010

I’m assuming you’re excluding some posts from the loop on the site you’re having problems with…

Reply

ad May 21, 2010

Ah, sure – i’m excluding the posts of one category for having a sideblog. That’s it, right?

Adam Baird May 21, 2010

Will be posting an updated tutorial next week with updated code to account for this.

Reply

ad June 1, 2010

Is the code already updated? Can’t see any changes.

Reply

Adam Baird June 1, 2010

No. I’ll be posting a completely new tutorial on this next week.

Matt Cheuvront May 26, 2010

Thanks for this tutorial – been looking for some help with hard-coding this without a plugin. Cheers my friend!

Reply

Radek June 1, 2010

Hi Adam

great post/tutorial especially if it helps me not use a plugin. Can you make it work for pagination of comments? If comments breaks into pages?

Thank you

R

Reply

John June 14, 2010

Any tips on how to fix this error on pages? (such as 404 page)

Warning: Division by zero in /thesis_17/custom/custom_functions.php on line 79

Reply

Dave July 1, 2010

Hi, I’m using Wordpress 3 and Thesis 1.7. When I cut and paste the custom php code into my custom file editor, and hit submit I get a 404 error (no other info). I thought it had something to do with the fact that I only have a 100 or so posts with 20 posts per page, so I changed the pages to display from 8 down to 4 and also 2, but no go.

Any thoughts on what might be causing this, could it be something with Wordpress 3?

Reply

ad July 2, 2010
Adam Baird July 2, 2010

I’ve yet to run this code with WP 3.0. I’m a bit baffled as to why this would happen though. There’s nothing in the code that should generate a 404.

Just to be sure, are you getting the Thesis 404 page or a blank white screen with an error message?

Reply

Dave July 2, 2010

Hi Adam, I’m getting the ‘You 404’d it. Gnarly, dude.’ within the content box of the page. The custom header and the right sidebar still show up, but the content box gives me a 404.

When I click the back button, the ‘offending code’ has been automatically removed from from the custom php file as though it was never pasted. Is it possible this problem I’m having is related to custom htaccess security protocols I have on my site, or should this code not be affected by such.

Thanks, Dave

Reply

Adam Baird July 2, 2010

Its entirely possible that the htaccess is the problem. Its impossible to know without taking a look at your code, but I’ve never heard of anyone having this problem.

You might try temporarily removing the custom rules and see if that solves the problem. You would at least know that was the problem. Hope that helps!

Reply

Dave July 2, 2010

Hey Adam, my guess was right. The fact that custom functions php refused to allow the code to even be posted was what led to that diagnosis, as normally it would allow the code to be posted and then if the code was wrong, futz up your site until you manually sftp’d to it to change the ‘offending code’.

So I tried just using sftp to securely paste that code into custom functions php and then it worked.

I must have some security settings that don’t allow for certain function calls to be placed in custom functions php through wordpress, as I’ve been editing it through wordpress admin without running into this error up till now.

Thanks for the code (as I really didn’t want to have to add another plugin) and for your quick responses.

Cheers, Dave

PS is there an easy way to adjust the code so that it doesn’t always show the first and last pages, or so that it only always shows the first page?

Reply

Dave July 4, 2010

Hi Adam, I spent some time looking over your code, and took a guess at removing the last number (which worked) and then guessed that Page $paged of $max_page was the piece of code I needed to remove to make the page navigation intro numbers disappear, and it was as well.

Thanks for using sensible naming conventions in your code so that I could decipher it even though I’m a noob to php coding.

Cheers, Dave

Reply

Utkarsh July 3, 2010

Awesome! You just saved me from plugin hell – one step towards being plugin free (well, almost) :D

Reply

dNoxs July 13, 2010

thanks for trick pagenavi, I have use this trick :D

Reply

Amílcar Tavares July 13, 2010

Thank You!!! I’ve been looking for this for a almost year!

Reply

Dave July 22, 2010

Hi Adam, I’m trying to get this to work for my tag pages as well. I spent the last couple hours playing with the code and was able to get it to show up in the tag pages if I replace if(!is_catergory with if(!is_tag.
But when I try to add elseif(!is_tag it doesn’t do anything. Now I’m kinda clued out as to what sORDER and sGROUP stand for, maybe you could clue me in.

I also tried creating a separate function called numbered_tag_nav, but that whole area with !is_single and !is_category screws me up.

Last but not least, I’m also trying to figure out how to have it return tag pages based on 10 per page instead of the current settings I have for the home page which is 25 per page. (this is why I though a separate function specific to tag pages would be good, but I couldn’t figure out how to do it)

Many thanks
Dave

Reply

Kumar July 23, 2010

Thanks Adam ! Great way to avoid a plugin. I got rid of two plugins after this tutorial which I used for Thesis paging.

Reply

Jamez Issac July 25, 2010

Hey bro i use it this nav function on mi site but it showing small font and numbering size as well
how can i improve it ..
take care mate

Reply

Talian August 24, 2010

Where do I place this function: function numbered_page_nav($prelabel = ”, $nxtlabel = ”, $pages_to_show = 8, $always_show = false) ? And where do I call this? And when I call the function, what are the parameters which I place into the function numbered_page_nav(????)? Can U help me please? I begin with wordpress.

Reply

Avinash August 31, 2010

Thanks a lot for the tutorial.

Its working like a charm on my blog. Thanks again.
Hope to read more tutorials like this in future. :)

Reply

DB September 2, 2010

Thanks for this.

I was looking for a little guide on how to add page numbers… I don’t understand why they are not making the page numbers navigation a default option in thesis.

Reply

Leave a Comment

{ 4 trackbacks }