I have a site that has changed its pagination structure, resulting in a huge amount of 404 errors (more posts are being shown per page than previously, so there are lots of pages that were once indexed in search engines that are now 404'ing).

What I want to do is create a function that will check whether a page number is greater than the max_num_pages value, and if that's the case interrupt the default wordpress behaviour which is to serve a 404 page, and instead 301 redirect it to either the home page, or better still the initial tag page chosen (we're only interested in tag pages in the overall structure).

What I don't know though is how - or more precisely when to use this function. I'm guessing that WordPress already has a function that checks this info, which in turn triggers the 404, so maybe I need to set it up as a filter to an existing pluggable function?

The function so far is

if (is_main_query() && !is_singular() && is_paged()) 
{global $wp_query;
$paged = intval(get_query_var('paged'));
$max_page = $wp_query->max_num_pages;
if($max_page < $paged){
echo 'page is greater than max';}
  • Side note: don't let search engines index your archive index pages. Only allow single post pages to be indexed. Archive-index pagination will change, either by changing the number of posts per page, or else simply by adding new posts. – Chip Bennett Nov 11 '12 at 17:08
  • That's a good point @ChipBennett - indiscriminate indexing of the archive pages has led us to this problem due to repagination; in general though I'm in favour of some indexing of tag/category pages (the first page only), as there are situations where tag/category pages can be important ranking pages bringing in significant traffic. – andy Nov 11 '12 at 19:24

If the rest of your function works you just need to add a call to wp_safe_redirect and hook the whole thing into WordPress. I think that the first hook that will have a populated $wp_query is wp. So alter the last part of your function...

if($max_page < $paged){

And then add the following after (outside) the function.


I think that should do it. You can setup infinite redirect loops so be careful.

Edit: The problem is the is_paged() check at the top of your function. If you try to access a pagination page that doesn't exist is_paged() returns false and none of the rest of your function runs. Remove that check, and hook to template_redirect. I tested this and it does work. In other words...

function redirect_tags() {
  if (is_main_query() && !is_singular() ) {
    global $wp_query;
    $paged = intval(get_query_var('paged'));
    $max_page = $wp_query->max_num_pages;
    if ( ($max_page < $paged) ) {
  • Thanks for that - though I still have a problem. The function to check max_num_pages to paged works up until a page when the max_num_pages < paged, at which point the automatic 404 kicks in, so I guess that I need to block that functionality first, before using the wp_safe_redirect. – andy Nov 9 '12 at 16:53
  • So you get the redirect before you function runs? Hmm... try remove_action('template_redirect','wp_old_slug_redirect'); and see if that helps. If it does maybe try hooking to template_redirect instead of wp. – s_ha_dum Nov 9 '12 at 17:29
  • Thanks again for your help @s_ha_dum Hooking into template_redirect didn't work either unfortunately. After reading link I tried hooking the function into 404_template, but then it redirects all 404's to the home page rather than just the ones that match the max_num_pages < paged formula. – andy Nov 10 '12 at 8:18
  • Edited my answer – s_ha_dum Nov 11 '12 at 16:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.