Mod_rewrite help



I’m a complete noob when it comes to mod_rewrite, and I could really use some help. I’m in the process of migrating my site from ExpressionEngine to WordPress, and would like to have as many inbound links to the old site continue to function in the new version. The basic structure of the EE urls is:

The basic structure of the WP urls will be:

So what I need to do is use mod_rewrite to remove the “index.php?/weblog/” string, and to replace underscores with hyphens. I’ve searched around and read everything I can find, and can’t get anything to work at all. Right now, my .htaccess file reads:

BEGIN WordPress

Options +FollowSymLinks RewriteEngine On RewriteBase / RewriteCond %{REQUEST_URI} ^/(stats|failed_auth\.html)/?(.*)$ [NC] RewriteRule ^.*$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] # END WordPress

This works mostly fine; anything with the “index.php?/weblog/” string is redirected to index.php. But if I add this above the WordPress info:

RewriteEngine On RewriteBase / RewriteRule ^/index\.php?/weblog/(.*)$$1 [R=301,L]

nothing changes – URI requests that include the “index.php?/weblog” string still redirect to the front page.

Similarly, adding something like this:

RewriteEngine On RewriteBase / RewriteRule ^([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)_(.*)$ $1-$2-$3-$4-$5-$6-$7 [E=underscores:Yes] RewriteRule ^([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)_(.*)$ $1-$2-$3-$4-$5-$6 [E=underscores:Yes] RewriteRule ^([^_]*)_([^_]*)_([^_]*)_([^_]*)_(.*)$ $1-$2-$3-$4-$5 [E=underscores:Yes] RewriteRule ^([^_]*)_([^_]*)_([^_]*)_(.*)$ $1-$2-$3-$4 [E=underscores:Yes] RewriteRule ^([^_]*)_([^_]*)_(.*)$ $1-$2-$3 [E=underscores:Yes] RewriteRule ^([^_]*)_(.*)$ $1-$2 [E=underscores:Yes]

has no effect whatsoever on the underscore/hyphen issue.

Any help would be really, really appreciated. I’m far out beyond the edge of my envelope here. Thanks!


Classic mistake. You need to remove the leading slash. There is a difference between server config and .htaccess files.

:cool: -//- One-time [color=#6600CC]$50.00 discount[/color] on [color=#0000CC]DreamHost[/color] plans: Use ATROPOS7


Thanks for that. But even the line

RewriteRule ^index.php?/weblog/(.*)$$1 [R=301,L]

has no effect at all. Any URI with the “index.php?/weblog/” still lands on the front page.


There was another obvious mistake. You cannot match the query string in the RewriteRule - use a RewriteCond instead.

:cool: -//- One-time [color=#6600CC]$50.00 discount[/color] on [color=#0000CC]DreamHost[/color] plans: Use ATROPOS7


Gotcha. But that’s what I need help with – what goes in the RewriteCond and what goes in the RewriteRule? For instance, if my RewriteCond line reads:

RewriteCond %{REQUEST_URI} ^(index.php?/weblog)/(.*)$ [NC]

is the RewriteRule line just

RewriteRule ^(.*)$ /$1 [R=301,L]

I don’t mean to be dense, but I honestly don’t know how to do this, and the documentation I’ve found hasn’t clarified things for me…


The best documentation is:
Apache Module mod_rewrite

You need to match both the path and the query string. So break that down. The pattern for the path is ^index.php$ and the for the query string is ^/weblog/(.*)

Having said that remember that RewriteRule matches the path and RewriteCond is used to match against variables. The variable for the query string is %{QUERY_STRING}

You need to use a backreference in the RewriteRule to the RewriteCond capture in the form of %N.

Also another obvious mistake is you don’t need an $ if what comes before it is .* in a pattern.

:cool: -//- One-time [color=#6600CC]$50.00 discount[/color] on [color=#0000CC]DreamHost[/color] plans: Use ATROPOS7


Thank you once again for your help, but I honestly am not understanding what you’re telling me. Telling me what the obvious mistakes are is only getting me so far when I don’t know what the right answers would even look like. I’ve gone over and over the Apache documentation all day, and it still reads like Greek. I appreciate your attempts to set me on the right path, but as everything I’m trying fails, I would really appreciate seeing what a correctly structured set of commands would look like.


I’m getting closer – at least insofar as I’m getting SOMETHING to happen now. I now have these statements in .htaccess:

RewriteCond %{QUERY_STRING} ^/weblog/(.*)$ [NC]
RewriteRule ^index.php$ /%1 [R=301,L]

Which results in a URL like:

being rewritten to:

Which is still totally incorrect, but which is at least doing something that I can understand. What I need to figure out how to do is to frame the pattern and substitution of the RewriteRule such that “post_name” replaces ALL of “index.php?/weblog/post_name”.

Slowly but surely…


Oh don’t give me that! :wink: It’s simple substitution. You got the syntax and the values, just plug the values into the syntax. Let’s begin.

The syntax is

RewriteCond TestString CondPattern
RewriteRule Pattern Substitution Flags

And you already know what the values are:

Pattern = ^index.php$
Substitution = /%1
Flags = [R=301]

TestString = %{QUERY_STRING}
CondPattern = ^/weblog/(.*)

:cool: -//- One-time [color=#6600CC]$50.00 discount[/color] on [color=#0000CC]DreamHost[/color] plans: Use ATROPOS7


Which is exactly what makes me convinced I’m missing something! :slight_smile:

What I’ve currently got is:

RewriteCond %{QUERY_STRING} ^/weblog/(.*) [NC]
RewriteRule ^index.php$ /%1 [R=301,L]

Which appears to be (almost exactly) what you’d get if you plug the values you list into the syntax. But with these statements in .htaccess, I wind up with an incorrectly rewritten URL ( – in other words, replacing only index.php with post-name, and not index.php plus everything that follows), and a redirect error (“the server is redirecting the request for this address in a way that will never complete”).

If I use EXACTLY the values you list (i.e., deleting the L from the flags), the server attempts to load the original URL ( and returns a 301 error page, with a link saying that the page has moved permanently – but to the original URL, which is clearly not true!


It should be:

RewriteCond %{QUERY_STRING} ^/weblog/(.*) [NC]
RewriteRule ^index.php$ /%1? [R=301,L]

The ? is needed at the end to remove the query string. Otherwise the old query string gets carried over.

:cool: -//- One-time [color=#6600CC]$50.00 discount[/color] on [color=#0000CC]DreamHost[/color] plans: Use ATROPOS7


Genius!!! Works like a charm. Thanks for your patience…


A final update: I managed to get this to work with my need to replace underscores with hyphens in the following fashion:

RewriteCond %{QUERY_STRING} ^/weblog/([^]+)([^]+)([^]+)([^]+)([^]+)([^_]+)$ [NC]
RewriteRule ^index.php$ /%1-%2-%3-%4-%5-%6? [R=301,L]

RewriteCond %{QUERY_STRING} ^/weblog/([^]+)([^]+)([^]+)([^]+)([^_]+)$ [NC]
RewriteRule ^index.php$ /%1-%2-%3-%4-%5? [R=301,L]

RewriteCond %{QUERY_STRING} ^/weblog/([^]+)([^]+)([^]+)([^_]+)$ [NC]
RewriteRule ^index.php$ /%1-%2-%3-%4? [R=301,L]

RewriteCond %{QUERY_STRING} ^/weblog/([^]+)([^]+)([^_]+)$ [NC]
RewriteRule ^index.php$ /%1-%2-%3? [R=301,L]

RewriteCond %{QUERY_STRING} ^/weblog/([^]+)([^_]+)$ [NC]
RewriteRule ^index.php$ /%1-%2? [R=301,L]

RewriteCond %{QUERY_STRING} ^/weblog/([^_]+) [NC]
RewriteRule ^index.php$ /%1? [R=301,L]