Forum Moderators: phranque
RewriteRule ^(testit)/?$ test.php?p=$1 [L,QSA] <!DOCTYPE html><html><body><img src="manual.png"></body></html>, uploaded it as /var/www/html/test.php, and also upload /var/www/html/manual.png. http://www.myDomain.com/testit in the browser, the page is rendered, and manual.png is displayed. http://www.myDomain.com/testit/ (not the trailing slash) in the browser, the page is rendered, but manual.png is a broken link. http://www.myDomain.com/testit, so it requests the image from http://www.myDomain.com/testit/manual.png which obviously doesn't exist. Why this only poses a problem when the main page has a trailing slash, I am uncertain. It is my understanding that it looks for "testit" plus 0 or 1 forward slashes and redirects to "test.php?p=testit".
RewriteRule ^(testit)$ /test.php?p=$1 [L,QSA] Not "redirects". Only "rewrites". Crucial difference.Good point.
Except, ahem, the target should start in / slash. (This is safer than using a RewriteBase, for reasons g1smd will explain.)Why so? Should I never use RewriteBase?
I assume the capture is just for illustraion purposes, since there would normally be no point to capturing literal text with no variation.My actual rules are shown below. My "intent" is to have the user see pretty URLs in their browser such as
http://www.myDomain.com/html1, http://www.myDomain.com/html2, http://www.myDomain.com/get-started, and http://www.myDomain.com/contact-us. html1 and html2 are just normal HTML pages located in my root directory, and should be rewritten to have the .html extension. Get-started and contact-us are two special cases which need PHP support, and might also need to pass some special data when used like http://www.myDomain.com/get-started/edit/123. Does this make any sense? Fortunately the solution is simple, and it concurrently avoids the Duplicate Content issue you'd be creating with that optional end slash. Decide which URL you want: with or without. Personally I'd go "without", using an extensionless URL rather than a fake directory. Happily this agrees with the physical location of the target file, so all supporting files now display as intended.I wish without end slashes.
You will see arguments in favor of using absolute URLs consistently. Personally I find the opposite is better in many cases.More on this in a bit.
I would also recommend adding some preceding rules:Please see my actual rules below. Can you provide some specific pointers?
- one that redirects requests for test.php?p=(something) to www extensionless URL
- one that redirects "with slash" to www without slash
- one that redirects all other non-www to www, preserving requested path
and ensure the site links to URLs without trailing slash. URLs with trailing slash denote a folder or index page of a folder.
Make sure that all links to css, js and images always begin with a slash and specify the full path to the file. This is a crucial step once you start using rewrites.This is contrary to Lucy's position. I would rather not have to do so. Is there a workaround?
Your PHP script now becomes responsible for returning 404 responses for non-valid requests that happen to be rewritten to be handled by the script.Good point. Will do. Only need to do for get-started and contact-us, right?
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
## If the request is for a valid directory, file, or link, don't do anything
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]
#remove the trailing slash. I haven’t really figured out this part.
RewriteRule (.+)/$ $1
# replace my-page/my-controller/data with corporate.php?p=my-page&c=my-controller&data=data
RewriteRule ^(contact-us|get-started)/([^/]+)/([^/]+)/?$ corporate.php?p=$1&c=$2&d=$3 [L,QSA]
# replace my-page/my-controller with corporate.php?p=my-page&c=my-controller
RewriteRule ^(contact-us|get-started)/([^/]+)/?$ corporate.php?p=$1&c=$2 [L,QSA]
# replace my-page with corporate.php?p=my-page
RewriteRule ^(contact-us|get-started)/?$ corporate.php?p=$1 [L,QSA]
#Replaces file if "." is not in the string (i.e. it will not replace file.html, but will replace file
RewriteRule ^([^.]+)$ $1.html [L]
</IfModule>
RewriteRule (.+)/$ $1
RewriteRule ^([^.]+[^./])/+$ /$1 [L] RewriteRule ^(([^/]+/)*[^./]+)/+$ /$1 [L]
RewriteRule(.+)/$ $1 RewriteRule ^(contact-us|get-started)/([^/]+)/([^/]+)/?$ corporate.php?p=$1&c=$2&d=$3 [L,QSA] RewriteRule ^(contact-us|get-started)(/([^/.]+)(/([^/.]+))?)?$ /corporate.php?p=$1&c=$3&d=$5 [L,QSA]
You'll need protocol and hostname on the rule target and the [R=301,L] flags here to ensure this is a redirect.Please elaborate.
The rule target in the final rewrites should begin with a slash.
The three rules beginning
RewriteRule ^(contact-us|get-started)/([^/]+)/([^/]+)/?$ corporate.php?p=$1&c=$2&d=$3 [L,QSA]
simplfies to
RewriteRule ^(contact-us|get-started)(/([^/.]+)(/([^/.]+))?)?$ /corporate.php?p=$1&c=$3&d=$5 [L,QSA]
RewriteRule^(contact-us|get-started)(?:/([^/.]+)(?:/([^/.]+))?)?$ /corporate.php?p=$1&c=$2&d=$3 [L,QSA]
What if "/" isn't found?
RewriteRule ^(contact-us|get-started)(?:/([^/.]+))?(?:/([^/.]+))?$ /corporate.php?p=$1&c=$2&d=$3 [L,QSA] Edit: Would these URLs even have a query string necessitating a QSA? I thought the whole point was to be "friendly"; if so, there's no need for the flag, though it won't do any harm.Only need to be friendly up to a point! I use a similar URL for ajax calls which might need additional information from the client.
Would these URLs even have a query string necessitating a QSA? I thought the whole point was to be "friendly"; if so, there's no need for the flag, though it won't do any harm.
?sortorder= parameter to the URL. The canonical URL will be the one without this parameter attached.