2

I recently dramatically changed the structure of my site and I'm getting errors from pages that existed on the past (and they will probably) exist on the future again.

eg:

in the past I had 44 pages (example.com/manual-cat/how-to/page/44/) and right now I only have posts to have 39 pages, but I will probably have more pages in the future.

How can I temporarily redirect ONLY if the page doesn't exists?

The reason I need to do this automatically is that I have 100 plus categories with errors and it would be impossible to manage this manually by doing individual redirects.

If this had to be done on the server side, please be aware that I'm on nginx.

5

You can detect non-existent pages only with WordPress. Normal URLs don't point to a physical resource, their path is mapped internally to database content instead.

That means you need a WP hook that fires only when no content has been found for an URL. That hook is 404_template. This is called when WP trys to include the 404 template from your theme (or the index.php if there is no 404.php).

You can use it for redirects, because no output has been sent at this time.

Create a custom plugin, and add your redirection rules in that.

Here is an example:

<?php # -*- coding: utf-8 -*-
/**
 * Plugin Name: Custom Redirects
 */

add_filter( '404_template', function( $template ) {

    $request = filter_input( INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_STRING );

    if ( ! $request ) {
        return $template;
    }

    $static = [
        '/old/path/1/' => 'new/path/1/',
        '/old/path/2/' => 'new/path/2/',
        '/old/path/3/' => 'new/path/3/',
    ];

    if ( isset ( $static[ $request ] ) ) {
        wp_redirect( $static[ $request ], 301 );
        exit;
    }

    $regex = [
        '/pattern/1/(\d+)/'    => '/target/1/$1/',
        '/pattern/2/([a-z]+)/' => '/target/2/$1/',
    ];

    foreach( $regex as $pattern => $replacement ) {
        if ( ! preg_match( $pattern, $request ) ) {
            continue;
        }

        $url = preg_replace( $pattern, $replacement, $request );
        wp_redirect( $url, 301 );
        exit;
    }

    // not our business, let WP do the rest.
    return $template;

}, -4000 ); // hook in quite early

You are of course not limited to a simple map. I have versions of that plugin with quite some very complex for some clients, and you could even build an UI to create that map in the admin backend … but in most cases, this simple approach will do what you want.

  • I didn't know there is a function called 404_template, in wp core... thanks! That being said, I guess (I'm not an expert in php) that $map is an array where I can also include a regular expression like this /old/path/page/[0-9]+?(/+)?$#'/ => /old/path/page/1/ ? – bpy Apr 17 '17 at 0:39
  • @Alex It's a hook, not a function. :) Yes, you can also use regular expressions, but then you have to use preg_match(), not a simple isset(). – fuxia Apr 17 '17 at 0:41
  • ...oh, ok! How can I use preg_match() to check if page doesn't exists today? – bpy Apr 17 '17 at 1:16
  • @Alex I have added an example with regular expressions to my sample code. – fuxia Apr 17 '17 at 1:25
  • I admit that I'm having difficulties to handle this, but your help is from great value to me. I will post the end result. Thanks! – bpy Apr 17 '17 at 1:30
0

In your .htaccess try:

<IfModule mod_rewrite.c>
RewriteEngine On

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.+) - [PT,L]

RewriteRule ^match/this/(.*)$ somewhere/else/$1 [L]
</IfModule>

So if it doesn't hit a file or a directory it will go to the rewrite rule at the bottom.

For nginx:

# nginx configuration
location / {
if (-e $request_filename){
rewrite ^/match/this/(.*)$ /somewhere/else/$1 break;
}
}
  • I'm on nginx so this code wont work. – bpy Apr 17 '17 at 0:07
  • I added the nginx version. – Jeff Mattson Apr 17 '17 at 1:50
-1

You can use and edit .htaccess file

# Redirect old file path to new file path
Redirect /manual-cat/how-to/page/44/ http://example.com/newdirectory/newfile.html
  • This must be done automatically. I edited the question above. – bpy Apr 16 '17 at 23:31

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.