Pretty urls (remove file extension, fake folders)
Posted: Wed Sep 14, 2016 5:07 pm
Not sure how many people would find this useful, but I've done this myself, but had issues with it messing up my sub folders, so I always avoided it for my main domain (since all my subdomains are really folders within my main domain).
An example of "pretty urls" is having:
Say you have:
To get around this, you have to exclude your rewrite rules on files and directories. The code I use in my .htaccess file:
The first line tells your server to default your directory index file to index.html, and if that doesn't exist, fall to index.php; most hosts have this already set up, so it's optional, but if you'd like to specify, you can (like make main.php the default).
The second line tells apache (the typical server most of us are using; .htaccess only works on apache servers) to start reading the subsequent lines as rules for rewriting.
This part is saying if the requested url is a file (the -f flag), do the next line, which is a wildcard capture of any filename, and doing nothing with it. A period (.) is matching any characters, and the asterisk (*) is saying zero or more of the preceding token. The dash (-) after that means to do nothing, and the [L] flag at the end means last rule for this particular condition.
This is pretty much the same as above, except the -d flag means directories/folders.
The last bit is the part that will give you the "pretty" urls. The first line captures any level one urls, like http://sub.domain.com/page and directs it to http://sub.domain.com/page.php (if you'd like it to redirect to another file type, change the .php at the end).
The ^ character indicates the start of your url pattern (regex), and the $ sign indicates the end, so all rewrite capturing patterns must follow that format. The characters between ^ and $ is the matching regex rule.
A "capturing group" is surrounded by parentheses ( and ), while the square brackets [ and ] surround your allowed character range. So for example the above line means any letters lowercase (a-z) or uppercase (A-Z). The + at the end means one or more of the preceding token. After that capturing group, the "\/" translates to just a "/" (the \ backslash escapes the / forward slash, you can just do a / forward slash, I only escape the character to be sure it's read as a forward slash just in case). The ? after the slashes means one or zero of the preceding token, so your pretty url will work with or without a / at the end.
A space follows that, then the matching file to redirect to. The "$1" means the first capturing group, and it will look for the first group with ( and ) around it and replace it with what you typed.
The second rewrite rule does the same thing, except it matches additional level files, so like page.php?name with the "$2" indicating the second capture group (the second group of letters it finds surrounded by parentheses).
If you want it to match a url of page.php?name=title then use this as the last line instead (modify it to match whichever form you like):
If you'd like to do level 3 urls:
And if you'd like your pattern to match more than just letters, replace the [a-zA-Z] with [a-zA-Z0-9-] to get letters, numbers, and dashes.
An example of "pretty urls" is having:
really direct to:
A lot of CMS scripts (like wordpress) will do this, and it's done through Mod_Rewrite in a .htaccess file. A few lines will do this, but the issue is it capturing actual folders/directories and incorrectly attempting to map them to a non-existing file.
Say you have:
but when you type it in the browser, you get a 404 error because your server tries to redirect it to:
Which of course doesn't exist.
To get around this, you have to exclude your rewrite rules on files and directories. The code I use in my .htaccess file:
Code: Select all
DirectoryIndex index.html index.php
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .* - [L]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [L]
RewriteRule ^([a-zA-Z]+)\/?$ $1.php
RewriteRule ^([a-zA-Z]+)\/([a-zA-Z]+)\/?$ $1.php?$2
The second line tells apache (the typical server most of us are using; .htaccess only works on apache servers) to start reading the subsequent lines as rules for rewriting.
Code: Select all
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .* - [L]
Code: Select all
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [L]
Code: Select all
RewriteRule ^([a-zA-Z]+)\/?$ $1.php
RewriteRule ^([a-zA-Z]+)\/([a-zA-Z]+)\/?$ $1.php?$2
The ^ character indicates the start of your url pattern (regex), and the $ sign indicates the end, so all rewrite capturing patterns must follow that format. The characters between ^ and $ is the matching regex rule.
A "capturing group" is surrounded by parentheses ( and ), while the square brackets [ and ] surround your allowed character range. So for example the above line means any letters lowercase (a-z) or uppercase (A-Z). The + at the end means one or more of the preceding token. After that capturing group, the "\/" translates to just a "/" (the \ backslash escapes the / forward slash, you can just do a / forward slash, I only escape the character to be sure it's read as a forward slash just in case). The ? after the slashes means one or zero of the preceding token, so your pretty url will work with or without a / at the end.
A space follows that, then the matching file to redirect to. The "$1" means the first capturing group, and it will look for the first group with ( and ) around it and replace it with what you typed.
The second rewrite rule does the same thing, except it matches additional level files, so like page.php?name with the "$2" indicating the second capture group (the second group of letters it finds surrounded by parentheses).
If you want it to match a url of page.php?name=title then use this as the last line instead (modify it to match whichever form you like):
Code: Select all
RewriteRule ^([a-zA-Z]+)\/([a-zA-Z]+)\/?$ $1.php?name=$2
Code: Select all
RewriteRule ^([a-zA-Z]+)\/([a-zA-Z]+)\/([a-zA-Z]+)\/?$ $1.php?cat=$2&page=$3