Support » Plugins » Check if posts lives somewhere else when old permalink triggers 404

  • Resolved microkid



    Here’s what I want to do:

    1. A user accesses my blog through an old permalink
    2. The system can’t find the post/page
    3. I grab the post slug form the requested path
    4. I search wp_posts WHERE post_name = ‘$slug’
    5. If I get a result, I present a 301 Moved Permanently header with the right path, if not I present a 404 error.

    I know there’s several ways to migrate permalink structures, but in this case there’s no clear format in the permalink that were used, so this is by far the most efficient way.

    I have managed to do this by hacking /wp-includes/classes.php:

    // BEGIN: check if document exists somewhere else
    			$parts = explode("/", $_SERVER['REQUEST_URI']);
    			if( preg_match("/\/$/", $_SERVER['REQUEST_URI'] ) ) {
    				$slug = addslashes( $parts[ (sizeof($parts)-2) ] );
    			else {
    				$slug = addslashes( $parts[ (sizeof($parts)-1) ] );
    			global $wpdb;
    			if( $guid = $wpdb->get_var( "SELECT guid FROM wp_posts WHERE post_name = '" . $slug . "'" ) ) {
    				header( "HTTP/1.1 301 Moved Permanently" );
    				header( "Location: $guid" );
    			else {
    				status_header( 404 );
    			// END: check if document exists somewhere else

    However, I obviously would rather do this in the shape of a plugin.

    Does anyone have any suggestions of how to trigger this process from a plugin, using a specific hook for instance? Or perhaps another solution I haven’t thought about?

    Thanks in advance.

Viewing 6 replies - 1 through 6 (of 6 total)
  • That is a very nice idea actually 🙂

    As far as a plugin hook, you should be able to use the ‘init’ action, as it is processed after WordPress loads, but before anything is sent to the browser (which you would need for your redirect to work).

    Thanks for your suggestion Aleister. I tried using ‘init’ as the hook for my action, but it was rather difficult to check if the request triggerd a 404, especially since is_404() isn’t defined yet at that point.

    What I did find out, is that it does work with the hook ‘template_redirect’. It appears the server hasn’t send any output to the browser yet so I can still send a 301 header.

    I’ll post the result soon.

    My only thought with ‘init’ would that it could be used if there was an easy way you could tell from the URL whether or not the link was good. That method would only work though if there was a consistent way to differentiate good and bad links just by looking (depending on the old permalink structure).

    Let us know how it works for you 🙂

    Here it is: Permalinks Moved Permanently

    I made a couple of small adjustments, added check for post_status = ‘publish’ to the query, and use get_permalink($ID) instead of $guid, to make sure no endless loops occur.

    Yeah I came up with this as a solution for the problem of not having consistent ‘old’ permalinks. Otherwise it would perhaps be easier to use an apache rewrite or something. This is more like a ‘catch-all’ solution.

    Great work! 🙂

Viewing 6 replies - 1 through 6 (of 6 total)
  • The topic ‘Check if posts lives somewhere else when old permalink triggers 404’ is closed to new replies.