Wordpress .htaccess Broken Down

As of WordPress 3.0, to create permalinks you will need to use the following .htaccess file:
# BEGIN WordPress
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
The goal of this post is to examine what the .htaccess rules are doing, and why they’re doing it. With this information you will be able to customize your own .htaccess file to suit the needs of your web application.

Line 1

# BEGIN WordPress
This is simply just a comment. The hash tag before any line is the method of commenting code in the .htaccess file.

Let's continue on.

Line 2

IfModule mod_rewrite.c
IfModule is a test that occurs within Apache, and it tests whether the mod_rewrite.c module is included in Apache. If mod_rewrite.c is included the code between and is run. If mod_rewrite.c isn’t included, the code within the if statements doesn’t get run. Simple enough?

Line 3

RewriteEngine On
RewriteEngine On tells Apache to turn on its" Rewrite Rules". That’s really all there is to this rule. Also, if you want to turn off all of your rules at once set this value to off.

Line 4

RewriteBase /
RewriteBase is a bit trickier because it affects how your other rules work, and it’s not immediately intuitive how it works.

When a url comes into Apache it looks something like this:
example-site.cz/blog/this-post

Before the url hits the rewrite rules, the domain name, and leading slash are stripped from the url:
blog/this-post

At this point, the url is run through all of the rewrite rules that you’ve specified, and changed accordingly.

Once those steps have been completed, the RewriteBase rule is applied. In the case of WordPress that line is RewriteBase /, so the leading slash is added to the url:
/blog/this-post

Line 5

This is blank so it does nothing.

Line 6

RewriteRule ^index\.php$ - [L]

Now we can get to the most important part of the .htaccess file – the RewriteRules. This particular rule is relatively easy to understand: if the path is index.php then perform no replacement (that’s what the dash means), and then exit out of the apache rewrite loop.

The final part of the rule [L] tells Apache to stop processing any remaining rules.

Line 7

RewriteCond %{REQUEST_FILENAME} !-f

This rewrite conditional uses a couple of special values, %{REQUEST_FILENAME} is a variable based upon the url you request, and !-f is an apache specific extension added to the regular expression language.

Let’s use an example for what the output of %{REQUEST_FILENAME} might look like. Let’s go to the webpage test-site.ca/fake_page.html. Within apache the value of %{REQUEST_FILENAME} gets set to reflect the physical filepath for our request. When I tested this on our servers the value came out like this: /mnt/stor0-wc0-dfw0/123456/test-site.ca/fake_page.html.

The second part of the RewriteCond would typically be a regular expression, however Apache provides some extensions that are being used. The first character – the exclamation mark (!) – is a negation. The second part -f asks whether the test string (in this case %{REQUEST_FILENAME} exists or not in the file system.

Taken together this RewriteCond makes the following check: If a file, taken from the variable %{REQUEST_FILENAME} does not exist on the file system, then return true.
Now RewriteCond is a cumulative rule, that is, you can’t just have a RewriteCond, you also have to have a RewriteRule in addition.

What happens now is the two conditions are combined together with a logical AND, and then the RewriteRule is applied when the two conditions are met.

Line 8

Line 8 is almost identical to Line 7. However it instead uses the -d special case, instead of the -f special case. The -d asks whether the path it is given is a directory or not.

Line 9

RewriteRule . /index.php [L]

This rewrite rule says that every request that goes to your website should be rewritten to instead go to /index.php. Now Line 7 and Line 8 come into play here, and if the conditions aren’t met, then /index.php isn’t used.

Line 10

IfModule simply closes the if statement that was started on Line 2.

Conclusion

So there you have it, the .htaccess file for Wordpress. Now that you know at least a little bit of what is going on, when things go haywire you will be better equipped to troubleshoot. HTACCESS files can become complex so it helps to know what the code is actually doing rather than blindly pasting in such an integral role in your website.