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.

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.

3 Answers 3


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:

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';
    case 'about-directory':
      $redirect_to = '/about-top-level-page';
    case 'services-directory':
      $redirect_to = '/services-top-level-page';
      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) {

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");

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:

  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?

  • Hi Mike, As always, you're amazing - thoroughly helpful and helpfully thorough! But -- this looks very scary and I'm worried I'll get in over my head as far as messing with php and core files... In the first part of your answer you say I can do it with .htaccess as @Kau-Boy shows, so your answer is an alternative to that, correct? On point #2, the directories are just "/products/" etc., no "-directory" -- there are a huge # of useless directories with a huge # of useless files within, I wanted a painless way to get rid of "everything except" the top level page within a small # of directories.
    – CJN
    Commented Aug 31, 2010 at 12:11
  • And, re: "Generating 404" - I want to avoid generating 404s, don't I? I'm try to 'catch' everything with 301's. That idea was that it might be an easy way to redirect "everything except" the few pages I identify in my other 301 rules-- so delete everything except those few pages; instead of user getting a 404, they get re-directed to home /random page I set? But,is that wise way to deal with it? As it turns out, a lot of the useless directories have their own images folder within also, so more pain with that... Anyway, I truly appreciate all your help (here and on other forums I see you on).
    – CJN
    Commented Aug 31, 2010 at 12:29
  • @CJN: Yes this is an alternate to using .htaccess the latter which I don't wish even on my worse enemies. :) Seriously, PHP is so much easier to write something robust than with .htaccess. Your question included '-directory which is why I used in my answer. I've done a lot of this and this is probably one of the most painless ways you can go. Find the patterns and code them into if statements, switch statements and regular expression and array matching. Just pick the example apart, it really is quite simple. Ask any follow up questions you need. Commented Aug 31, 2010 at 18:15
  • @CJN: Your question was worded such that I thought maybe you wanted them but yes, avoid 404s. Realize that URLs are a tree of path segments separated by slashes and just write logics to handle that; just divide and conquer. And ask if you stumble. While it may look hard it really isn't compare to so many other things, it's just brute force inspection and mapping. Commented Aug 31, 2010 at 18:19

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.

  • boy, Thanks very much. It looks like I might have had the right ideas - but hard to tell because you say "(not sure if they are all correct)". I don't think I'll need to worry about getting into the database to deal with permalinks. I have wordpress set up appropriately and have a good handle on that. Thanks again for chiming in - I feel more confident going forward now.
    – CJN
    Commented Aug 31, 2010 at 12:39

I use this: Simple 301 Redirects plugin - used it for a few pages prior, and I am soon to move my web design site with all it's files and folders inside of my WP files.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.