Creating 301 Redirects for Post, Page, Category and Image URLs?

I fear this may be too much to ask here, so if so, please feel free to tell me of another place to learn.

Help with Redirections

I’m cleaning up a badly developed site and migrating wordpress from a subdirectory. I’ve spent hours trying to wrap my head around the logistics of redirections and regex. I think I’m getting a handle on it, but would really appreciate confirmation that I’m doing this right, and any advice on best practices. If anyone knows of any good tutorials with how-to examples, I’d appreciate that too.

Read More

If anyone knows of really simple plugins for this, I’d be extremely grateful. I’ve been looking at the Redirections plugin, but find it very confusing (headache!). In any case, my ideas below (sources are followed by => then target) are what I’ve gathered from the Redirections instructions and screenshots and other tutorials I’ve scoured. I’m pretty sure that they’d be applicable regardless of whether I put them directly in the .htaccess file or use Redirections or another plugin?

So, here’s what I’m trying to accomplish and how I think it needs to be done :

  1. To move WordPress from the subdirectory to the root:

    /wp/(.*) => /$1
    
  2. For all pages currently within subdirectories in the root, I want to delete and/or combine a bunch of pages into one top level page:

    /products-directory/(.*) => /products-top-level-page  
    
    /about-directory/(.*) => /about-top-level-page  
    
    /services-directory/(.*) => /services-top-level-page  
    
  3. For a bunch of top-level pages matching a specific pattern, I want to direct them into specific categories, e.g. the file names all start with the same two words like this: same-word-variation-variation.html and I want them to keep their existing file names — if I set my permalinks to end with `.html`, this will work, I believe:

    /same-word(.*) => /newcategory/$1
    

    How would I create the rule if I don’t have permalinks ending in `.html`? (I think I saw ! is the “not” character, but not sure how to use here — is it):

    /same-word(.*) => /newcategory/$1!.html
    
  4. And then, once I have the specific pages identified and redirected as above, I’ll be deleting all the rest (garbage) and want to send users to the home page (or maybe a random post?).

    So, 2 questions here:

    1. How do I create the rule that says “for everything except the files already redirected as above, do this”

    2. How would I stop that rule from applying to new pages and posts I create from now on?

    One idea is that by deleting, I’d be getting a 404 page not found, so I should create the rule for the 404 page itself? Is that what I want to do?

    As I’ve said, the site has been badly developed (with the client instructing people to just “throw up a page” with no regard for proper architecture, SEO, etc.) — it has virtually no ranking or external / back links to worry about, but I want to understand the best approach from an SEO and proper development perspective.

  5. Also, should I move existing images etc. into the wp-content directory or leave them in their existing sub-directory/ies? My inclination is to really go for a ‘clean-sweep’ – get rid of everything that seems untidy, but I’m not sure if this would be more work than it’s worth…

Thanks in advance for any and all guidance.

Related posts

Leave a Reply

3 comments

  1. Hi @CJN:,

    Your first question, moving the WordPress directory is handled differently from the rest.

    Moving WordPress from Subdirectory to Root:

    Go into /wp-config.php and add the following to defines (using your client’s domain instead of example.com of course):

    define('WP_SITEURL', 'http://example.com');
    define('WP_HOME',    WP_SITEURL);
    

    301 Redirects using template_loader and wp_safe_redirect()

    You can solve most of the rest of your questions by modifying .htaccess as @Kau-Boy shows how, or you can just do it in PHP. WordPress has a template_redirect hook you can use for this along with the wp_safe_redirect() function to redirect with a 301 HTTP status code. As you can see the rest is just brute for PHP code and a bit of regular expression magic sprinkled in. You can put this code practically anywhere in your theme’s functions.php file:

    add_action('template_redirect','my_template_redirect');
    function my_template_redirect() {
      $redirect_to = false;
      list($url_path,$params) = explode('?',$_SERVER['REQUEST_URI']);
      $path_parts = explode('/',trim($url_path,'/'));
      switch ($path_parts[0]) {
        case 'products-directory':
          $redirect_to = '/products-top-level-page';
          break;
        case 'about-directory':
          $redirect_to = '/about-top-level-page';
          break;
        case 'services-directory':
          $redirect_to = '/services-top-level-page';
          break;
        default:
          if (preg_match('#same-word(.*)#',$path_parts[0],$match)) {
            $category = str_replace('.html','',$match[1]);
            $redirect_to = "/newcategory/{$category}";
          } else {
            // Do whatever else you need here
          }
      }
      if ($redirect_to) {
        wp_safe_redirect($redirect_to,301);
        exit();
      }
    }
    

    Consider Usability and Not Just SEO?

    I would ask if you really want to do #2? IMO that makes a site a lot less usable for users than one that is optimized solely for perceived SEO (and as founder and one time co-organizer of this group I’m not an SEO neophyte.) I’d much rather see you just drop the "-directory" from the first segment of the URL path. JMTCW anyway.

    Generating 404 Pages?

    If you need to issue a 404 you can do it with header:

    header("HTTP/1.0 404 Not Found");
    exit;
    

    However I think that’s not what you want to do, correct? I think you can achieve whatever redirect logic you need by modifying the PHP function above and responding to the HTTP request with a 301, right?

    Importing Images into Media Library and 301 Redirecting

    You could move them into the media library and doing so would allow you to manage them moving forward. Here’s a plugin that might help (although I’m not sure if it is working with 3.0; if not it might be a good code base to work with anyway):

    Hardcoding Image URL 301 Redirects using an Array

    Then since it would be a one-time thing you could simply hardcode your image URLs into an array and use them to match in your redirection function. Modifying the default in the switch statement from the code above it might look like this:

    default:
      if (preg_match('#same-word(.*)#',$path_parts[0],$match)) {
        $category = str_replace('.html','',$match[1]);
        $redirect_to = "/newcategory/{$category}";
      } else {
        $images = array(
          '/images/image1.jpg' => '/wp-content/uploads/2010/08/image1.jpg',
          '/images/image2.jpg' => '/wp-content/uploads/2010/08/image2.jpg',
          '/images/image3.jpg' => '/wp-content/uploads/2010/08/image3.jpg',
          );
        if (in_array($url_path,$images)) {
          $redirect_to = $images[$url_path];
        } else  {
          // Do whatever else you need here
        }
      }
    

    Using preg_match() to 301 Redirect Images by URL Pattern

    Of course if your image URLs follow a pattern you could streamline much or all of the images array using a preg_match() instead, like so:

    if (preg_match('#^/images/(.*)$#',$url_path,$match)) {
      $redirect_to = "/wp-content/uploads/2010/08/{$match[1]}";
    }
    

    Hope this helps?

  2. There is a plugin for changing from one permalink struture to another, but I am quite sure that this will not be enough for your needs. You will have to use some .htaccess rewrite rules. I try to give you some examples for your need (not sure if they are all correct). Include all those lines into a file called “.htaccess” in the root of your server. Out it above of the wordpress rules:

    # BEGIN WordPress
    <IfModule mod_rewrite.c>
    RewriteEngine On
    # your rules start here. Keep the following lines that has been produced by wordpress
    RewriteBase /
    RewriteRule wp/(.*)$ /$1 [R=301]
    RewriteRule /products-directory/(.*)$ /products-top-level-page [R=301]
    RewriteRule /about-directory/(.*)$ /about-top-level-page [R=301]
    RewriteRule /services-directory/$ /services-top-level-page [R=301]
    RewriteRule /same-word(.*)$ /newcategory/$1 [R=301]
    

    The flag [R=301] will tell the client browser or search engine, that it is a permanent redirect.

    You will probably want to update all the permalinks within your wordpress database. I wrote an article about updating string in the database. Unfortunately I haven’t translated the post, yet. But the queries should be clear, otherwise just use the MySQL docs.