Update 2012/07/15 all code updated with the new .htaccess rules (changed in WP 3.0). The code in this article should work with all versions of WordPress. </update>
I recently performed a series of tests on a fresh installation of WordPress 2.8.6 to determine the exact htaccess rewrite rules that WordPress writes to its htaccess file for various permalink configurations. Under the WP admin option menu, WordPress lists four choices for permalink structure:
- Default:
http://perishablepress.com/press/?=123 - Date and name based:
http://perishablepress.com/press/index.php/2006/06/14/sample-post/ - Numeric:
http://perishablepress.com/press/index.php/archives/123 - Custom:
/%year%/%monthnum%/%day%/%postname%/
The "default" option is to not use permalinks. The "date and name based" setting invokes the /index.php/%year%/%monthnum%/%day%/%postname%/ rule pattern. The "numeric" setting invokes the /index.php/archives/%post_id% rule pattern. And the "custom" setting invokes whatever pattern is specifically chosen. For our "custom" option, we chose the /%category%/%author%/%postname%/ pattern.
For the test, we began with the common "date and name based" permalink configuration. Then, after invoking the chosen permalink structure, the htaccess file was downloaded and the new WP rules were recorded. After this, the admin permalink settings were switched back to the "default" configuration. Finally, we deleted the new rules and uploaded the htaccess file. This process was diligently repeated for each different permalink configuration. It should also be noted that blog performance was checked during each round of testing.
The results indicate conclusively that WordPress uses the exact same set of htaccess rules for all permalink configurations. Surely this information is available elsewhere on the internet, however we were experiencing several inconsistencies related to permalink structure that inspired us to determine for ourselves the precise htaccess rules for WordPress permalinks.
Without further ado, the htaccess rules for all WordPress permalinks1 are precisely either #1 or #2:
[ #1 ] If WordPress installed in the root directory »
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
[ #2 ] If WordPress installed in a subdirectory called "foo" »
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /foo/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /foo/index.php [L]
</IfModule>
# END WordPress
1 Note: These results are valid for standard permalink structures invoked via a standard WordPress install and may not operate effectively for non-standard or highly specialized configurations. We assume that if you are hard at work hacking and tweaking, you must know what you are doing.
96 Responses
Perishable – January 2, 2008
Excellent news, Adrian — I am glad to hear that the code worked for you. :)
Happy New Year!
Kyle – January 8, 2008
Thank you, Thank you! I spent hours last night trying to figure this out and stumbled upon this today!
Perishable – January 8, 2008
My pleasure, Kyle — happy to help! Excellent looking site you have, btw ;)
scott – January 17, 2008
Hi Perishable,
I’m having a similar issue with wordpress and .htaccess.
I have multiple subdomains under one server. Within each subdomain is a WordPress blog. To avoid canonicalization, I rewrite
domain.comtowww.domain.com. Unfortunately, wordpress only works as a folder extension of highlevel domain. (eg.maindomain.com/subdomain/blog/)I tried a few tricks mentioned here and on WP.org, but to no avail.
I was hoping with your experience you might have a quick solution.
Thanks in advance,
Scott
Perishable – January 20, 2008
Hi scott,
I want to help, but I am having some difficulty understanding your question.. What exactly are we trying to do here? I see that you are working with WP installs on various subdomains, and that you are redirecting non-www URLs to their www counterparts..
— what am I missing?
sygyzy – February 20, 2008
my site was hacked last night and as part of my research to restore it, two articles of yours came up. I noticed this because of your theme design. Thanks for posting the information. It’s been very helpful.
Perishable – February 26, 2008
My pleasure, sygyzy — happy to help! ;)
Jummy – March 22, 2008
Thank you so much for putting this up. I read it and the comments others left but I think my situation is a bit different and I was hoping you’d be able to help me out.
My blog is located at http://domain.ca/blog. I have a .htaccess file in that folder with chmod 666
I put your code from #2 above into the .htaccess file, changing the two instances of ‘foo’ to ‘blog’ (am I supposed to remove the #?)
I activated date and name-based permalinkss then I went to my site and click on the title of an entry, with the hope that it would show only that entry on the page and the new improved permalink above. Instead, my header image disappeared and all the entries on the page are still visible.
However, when I use the default permalinks and click on the title of the entry, the single entry shows up and I can still see my header image.
I hope this makes sense. Would you have any idea why this is acting this way?
Thank you for your time!
Perishable – March 25, 2008
Hi Jummy, I am not too sure about what the issue may be with your permalinks, but I can try to address a few concerns in hopes that something might click. First, you should not remove the
#(pound signs) from the code. They are used in htaccess to denote a line containing a comment, which is information that should not be processed by the server. Second, keep in mind that the htaccess code provided in this article is the code used for all permalink formats (default, name-only, date-only, etc.), and should be an exact replica of the code that is automatically generated via WordPress. Finally, after you have implemented permalinks on your site, you may want to investigate any plugins, scripts, and/or theme code involved with the display of your header image. Beyond this, it is really difficult to say without a more thorough understanding of your particular WordPress setup and server environment, etc. In any case, I hope that helps provide some clues for you to consider. Good luck!Jummy – March 25, 2008
Thank you very much! I think the whole process of submitting my problem to you and thinking on what you said helped me figure out my problem.
My header image wasn’t showing up with individual posts because I had a relative link instead of the absolute link, so it wasn’t related to the above code not working.
I appreciate your help. :)
Perishable – March 25, 2008
That’s great, Jummy! I am glad to hear that everything is working now. Thanks for the follow-up! Cheers :)
Russell – April 7, 2008
So I’m curious if it is then possible to password-protect just one WordPress url. (WordPress has a post-level protection built-in but it stinks.) Would you not write this beneath your rewrite rules?
# password-protect single file<Files index.php?p=67>AuthType BasicAuthName "This area is restricted to registered users"AuthUserFile /icslte/.htpasswdRequire valid-user</Files>