Mod_Rewrite Made Easy-er

January 31, 2015 8:20 pm Published by Leave your thoughts

I am bold enough to admit that I do not know everything. Today I learned about mod_rewrite and all it’s fun quirks. There were, in my opinion, two obstacles to overcome. The first was my self and my own expectations. The second was the expertly written articles and blogs I read in trying to learn how to rewrite a url to be SEO friendly.

Let me digress for a moment. I am not trying to be facetious by claiming my readings were “written by experts.” Now, you may be thinking, ” well, shouldn’t they be!?” I defend my argument by simply stating that I used to be an expert writing instructional manuals to operate machinery that I had designed. The problem was: in my expertise I forgot that people not involved do not know the same vocabulary. I forgot that my anagrams, shortcuts, and verbage was known only to myself and other experts, not the people for whom the article was written. That being said, I am going to attempt to explain, in general, how to write an .htaccess file.

The other obstacle was overcoming my own expectations. It turned out that I was making the .htaccess file much more complicated than necessary. What I did not realize, and this is the important part, was that the url should be written exactly as you want it to look!

As you know, to effectively use a dynamic, database-driven, website you make webpage requests, or queries, using the url. However, this does not make Search Engines happy. Here is an example. To call a certain page within a particular category looks something like this: http://example.com/?page_name=products&category=toothbrush. This url would display a product webpage with toothbrushes… teethbrushes… what is the plural of that… nevermind… you get the idea. But the SEO friendly version of this same url is http://example.com/products/toothbrush.

When I first started out, I thought, because I was sending my query through the url, that my url should be the first one: http://example.com/?page_name=products&category=toothbrush and that the .htaccess file would make it look pretty. As it turns out, I needed to write the url as http://example.com/products/toothbrush. I had it backwards.

The .htaccess file takes the SEO friendly url and uses the designations defined in the RewriteRule to send a query to the server. The user never sees the query url, just the pretty one. Now, I am not going to go into all the various methods that can be used, that is another article for another day. I will simply define a basic pattern as an example. To get the  SEO friendly url to work your .htaccess file should look like this:

Rewrite on
Options +FollowSymlinks
RewriteRule ^([a-z]+)/([a-z]+)/?$ ?page_name=$1&category=$2

For the last line, an alternate, and more expansive rule could look something like this:

RewriteRule ^([a-zA-Z0-9-]+)/([a-zA-Z0-9-]+)/?$ ?page_name=$1&category=$2

And an even more inclusive condition would be:

RewriteRule ^(.*)/(.*)/?$ ?page_name=$1&category=$2

So I upload that to the server and, voilà, the url looks pretty, but my stylesheet and all my images disappear! Great. Ok, the fix to that is one of two things.

The first is adding a conditional clause to your .htaccess file:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

Or you can use an HTML tag in your template file at the top of your <head> section called <base>.
I will not go into any explanation for this except to show you how it is written (you can read more here):



...

In the example above replace http://example.com/ with your own url.

So, yay!, now everything works and looks pretty! In closing, let me break this down for you. First, the .htaccess file in full:

Rewrite on
Options +FollowSymlinks
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-z]+)/([a-z]+)/?$ ?page_name=$1&category=$2

Here is the breakdown, line by line:

Rewrite on  – A switch to turn on the command to tell apache to re-write the url (this one is kind of obvious).

Options +FollowSymlinks  – This is not a necessary command, and you may not need it. It tell apache to follow links that do not contain a real path to a file. An example is: http://example.com/myfile.pdf is a “symbolic” link to /home/exampledomain/docs/pdf/myfile.pdf and with this command enabled the link target will be retrieved.

The following two conditions are switches for files ( -f ) and directories ( -d ) with the exclamation point negating them. So, it reads like: “IF the uri is not a file or a directory, then rewrite the url following the rule.” It is important to note that the condition(s) will only be used for the next single rule, not all the rules following the conditions. New conditions must be written for each rule. And these two conditions are written as:


RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

And now finally the fun part, the actual re-write rule, which I will break down into smaller bits to explain:


RewriteRule ^([a-z]+)/([a-z]+)/?$ ?page_name=$1&category=$2

This is how it works. The first part (before the space) is tell the server to “look for things that match these parameters in the url string. This is how it looks. The Apache server already knows what your base uri is (http://example.com/), so this can be excluded. We use “regular expressions” to identify our search pattern. The ^ says this is the beginning. The parenthesis say, “what is enclosed in between these parenthesis is what you will use as the variable value in the url string we send to the server when requesting the file.” One set of parenthesis for each value. In my example there are two, each separated by a “/” as in your url. Then in the brackets ( [ ] ) we put what we want to look for and filter. The plus symbol ( + ) states that this pattern may be repeated more than once. There is a really good section on the apache.org website about that here. In this example I have it set to only look for lower case alpha characters (a-z). In the first alternate rule above I also included upper case alpha characters (A-Z), numeric characters (0-9), and dashes ( – ). In the second alternate rule I set it to look for anything (.*). You will need to decide what you want to look for as your parameters.

Putting this all together, in the write order (pun intended), correctly, can give you nice urls that call dynamic webpages for your database driven websites. I hope this helps.

The official apache.org directions start here. Pick your server version and enjoy the read!

Tags: , , , , ,

Categorised in:

This post was written by dmbarber

Leave a Reply