Forum Moderators: phranque

Message Too Old, No Replies

Overwrite Wordpress's RewriteRule with custom RewriteRule in .htaccess

How to make Wordpress to accept custom RewriteRule in .htaccess file

         

caruso_g

5:43 pm on Jan 27, 2010 (gmt 0)

10+ Year Member



I made a transition of a blog from Joomla to Wordpress, and I had to write a lot of rules for old internal links to posts to make Wordpress accept them in its own query way.
The problem is that is seems hard to use Wordpress RewriteRule together with custom ones since once activated WP ones, custom rules stop working.

I found a topic [webmasterworld.com] that was just about this issue, but my particular situation is different, so I didn't understand how to correct it.

Following is the .htaccess file I am trying to use:


RewriteEngine On
RewriteBase /
#
# for links like: /article-title-0012345.xhtml
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)-00(\d{1,5})\.xhtml?$ /?p=$2 [R=301,NC,L]
#
# for links like: /article-title-12345.xhtml
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)-(\d{1,5})\.xhtml?$ /?p=$2 [R=301,NC,L]
#
# for links like: /content/view/12345
RewriteRule ^content/view/(\d{1,5}).*?$ /?p=$1 [R=301,NC,L]
#
# for links like: /index.php?key=value&key=value&id=12345.xhtml (THANKS JIM ;) )
RewriteCond %{QUERY_STRING} ^([^&]*&)*id=([0-9]{1,5})(&.*)?$
RewriteRule ^(index\.php)?$ /?p=%2 [R=301,NC,L]
#
# for old rss link
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteRule ^feed\.rss$ /?feed=rss2 [R=301,NC,L]
#
# for links like: /2009-W30 or /2009-30 (it's a weekly archive)
RewriteRule ^(\d{4})-w(\d{1,2})/?$ /?Year=$1&w=$2&order=DESC [NC,L]
RewriteRule ^(\d{4})-(\d{1,2})/?$ /?Year=$1&w=$2&order=DESC [NC,L]
#
# for links like: /7731
RewriteRule ^(\d{1,5})/?$ /?p=$1 [NC,L]
#
# for links like: /article-title-7731
RewriteRule ^.+-+(\d{1,5})/?$ /?p=$1 [NC,L]
#
# for links like: /7731-article-title
RewriteRule ^(\d{1,5})-+.+/?$ /?p=$1 [NC,L]
#
RewriteRule ^contatti/?$ /?page_id=2 [NC,L]
#
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
#
# END WordPress
#
RewriteCond %{HTTP_HOST} ^example.com$ [OR]
RewriteCond %{HTTP_HOST} ^www.example.com$
RewriteRule ^index2\.php$ "http\:\/\/www\.example\.com\/\?feed\=rss2" [R=301,L]

Thanks in advance for your help! ^_^

[edited by: jdMorgan at 6:41 pm (utc) on Jan. 27, 2010]
[edit reason] Fixed link, formatting, and smilies in code. [/edit]

jdMorgan

7:01 pm on Jan 27, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Rule order is important: Move your final rule (the redirect at the end) to a position above all of your internal rewrite rules.

This will likely fix your problem.

To avoid many problems, order yours rules with all external redirects first, in order from most-specific (fewest URLs affected) to least specific, followed by all internal rewrites, again in order from most- to least-specific, and always include an [L] flag at the end your rules (as you have already done here).

BTW, that final rule can be more efficiently and correctly coded as


RewriteCond %{HTTP_HOST} ^(www\.)?example\.com
RewriteRule ^index2\.php$ http://www\.example\.com/?feed=rss2 [R=301,L]

If you don't have any subdomains or any additional domains hosted in this same server filespace, then the RewriteCond isn't needed at all.

The <IfModule> container around the WP code is unnecessary unless you want that code to fail silently on a server where mod_rewrite is not available.

The redundant "RewriteBase and RewriteEngine On" directives in the WP code are also not needed. Further, you can double the performance of that rule by adding an exclusion:
# BEGIN WordPress
#
RewriteCond %{REQUEST_URI} !^/index\.php$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
#
# END WordPress

Further performance gains can be had by excluding images and "well-known" files from that rule as well, replacing the first RewriteCond with:


RewriteCond %{REQUEST_URI} !(^/index\.php¦\.(gif¦jpe?g¦png¦ico¦css¦js)¦^/robots.txt¦/sitemap\.xml)$

Replace all broken pipe "¦" characters in the code above with solid pipe characters before use; Posting on this forum modifies the pipe characters.

Jim

g1smd

7:13 pm on Jan 27, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Further thoughts on avoiding canonicalisation problems.

1. Redirects should usually be hard coded to also include the domain name in the target URL. You do not want non-www to redirect to non-www and www to redirect to www. You want all to redirect to the canonical version.

2. Redirect code for URL requests like

/index.php?key=value&key=value&id=12345.xhtml
should have a more broad pattern that can recognise requests with parameters in a different order, and in aNy Case, and with extra parameters and/or with parameters missing. Perhaps just key it off the ID parameter whether or not other parameters are even present.

3. Rewrites should NOT have wildcard items in the pattern such that different URL requests handled by the rewrite present the same content. That is, the rewrite should work either with or without a trailing slash, not both (clue: the non-canonical one should redirect to canonical in a preceding rule). Likewise the [NC] flag on a rewrite may also be introducing Duplicate Content issues.