Example of current file structure:
example.com/foo.php
example.com/bar.html
example.com/directory/
example.com/directory/foo.php
example.com/directory/bar.html
example.com/cgi-bin/directory/foo.cgi*
I would like to remove HTML, PHP, and CGI extensions from, and then force the trailing slash at the end of URLs. So, it could look like this:
example.com/foo/
example.com/bar/
example.com/directory/
example.com/directory/foo/
example.com/directory/bar/
example.com/cgi-bin/directory/foo/
I am very frustrated because I've searched for 17 hours straight for solution and visited more than a few hundred pages on various blogs and forums. I'm not joking. So I think I've done my research.
Here is the code that sits in my .htaccess file right now:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(([^/]+/)*[^./]+)/$ $1.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]|/)$
RewriteRule (.*)$ /$1/ [R=301,L]
As you can see, this code only removes .html (and I'm not very happy with it because I think it could be done a lot simpler). I can remove the extension from PHP files when I rename them to .html through .htaccess, but that's not what I want. I want to remove it straight. This is the first thing I don't know how to do.
The second thing is actually very annoying. My .htaccess file with code above, adds .html/
to every string entered after example.com/directory/foo/
. So if I enter example.com/directory/foo/bar
(obviously /bar
doesn't exist since foo
is a file), instead of just displaying message that page is not found, it converts it to example.com/directory/foo/bar.html/
, then searches for a file for a few seconds and then displays the not found message. This, of course, is bad behavior.
So, once again, I need the code in .htaccess to do the following things:
- Remove .html extension
- Remove .php extension
- Remove .cgi extension
- Force the trailing slash at the end of URLs
- Requests should behave correctly (no adding trailing slashes or extensions to strings if file or directory doesn't exist on server)
- Code should be as simple as possible
@Kronbernkzion excellent. The only issue I'm having now is 404's don't seem to work right and leads me to a real funky place, I can't even use an absolute 404 redirect.
ErrorDocument 404 http://www.google.com
Did you come across this? How did you get past it?
Aside from the 404 rewrite, the full code I've used was:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} (.*)/$
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule (.*)/$ $1.html [L]
RewriteCond %{REQUEST_URI} (.*)/$
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule (.*)/$ $1.php [L]
RewriteCond %{REQUEST_URI} (.*)/$
RewriteCond %{REQUEST_FILENAME}\.cgi -f
RewriteRule (.*)/$ $1.cgi [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f [OR]
RewriteCond %{REQUEST_FILENAME}\.php -f [OR]
RewriteCond %{REQUEST_FILENAME}\.cgi -f
RewriteRule .* %{REQUEST_FILENAME}/ [R=301,L]
</IfModule>
/foo.html
and/bar.php
, are you going to have a rule that explicitly matches/foo/
to/foo.html
and/bar/
to/bar.php
? Or do you need a single generic entry that will match/foo/
to both/foo.html
OR/foo.php
(depending on which one exists)?