SEO Friendly URL's with .htaccess - apache

Had a look around before posting this and couldn't find anything that matched with my specific problem.
On my website, I prefer to have my URL's without .php in them, so I have that set up in in my .htaccess file and it works perfectly. At the moment I have a page on my site called "Albums", that are the top albums of the year currently. However, I'd like to also do it for next year and so on. Now, I can do it as albums?date=2017, but that looks ugly. I'm wanting to do it as example.com/albums/2017, as it looks a lot nicer and it's more SEO Friendly.
What I have in my HTACCESS is as follows:
RewriteEngine On
# Remove PHP from file names
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]
# Redirect albums.php?date=2017 to albums/2017
RewriteCond %{THE_REQUEST} \s/albums\?date=([0-9]+)\s [NC]
RewriteRule ^ /albums/%1? [R=301,L]
RewriteRule ^albums/([0-9]+)$ /albums?date=$1 [L]
Options -Indexes
# Error Document Redirects
ErrorDocument 403 http://example.com/errors/403
ErrorDocument 404 http://example.com/errors/404
albums.php?date=2017 works without the the redirects, but when I put the redirects in, it sends you to /albums/2017, but doesn't show anything on the page. If I remove my "Remove PHP from file names" redirections, it does show the information on the page. So obviously I've worked out that the error is caused due to the "Remove PHP from file names" section of the file, I'm just not sure how to fix it.
I'm not hugely knowledgeable with .htaccess and the RewriteEngine, only know enough or very basic things, so apologies if this looks horrendous. I've had a look to try and make sure that I've not made a duplication question, but sorry if I have,

Try it like this,
RewriteEngine On
# removed .php extension
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([\w-]+)$ $1.php
# you can directly use album/(date) in your url using this rule
RewriteCond %{REQUEST_FILENAME}.php !-f
RewriteCond %{REQUEST_FILENAME}.php !-d
RewriteRule ^([\w-]+)/([\d]+)$ $1.php?date=$2

Figured it out.
# Redirect albums.php?date=2017 to albums/2017
RewriteRule ^albums/([^/]*)$ /albums?date=$1 [L]
# Remove PHP from file names
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]

Related

Apache2 mod_rewrite pattern restriction?

So I have a site that I want to make SEO friendly by using mod_rewrite. I want to make the URLs easy to remember by dropping the .php on the end of them and using mod_rewrite to re-attach them later on. So for example say http://example.com/about would point to http://example.com/about.php. I have the RewriteRule that should work from my experience but for some reason doesn't.
My rule:
RewriteEngine On
RewriteRule ^/?about$ about.php [L]
RewriteRule ^/?faq$ faq.php [L]
Now these rules don't work like that exactly. it seems that if I rename the files to blah.about.php and blah.faq.php and change the RewriteRule lines to reflect the new filenames it works.
Is this a restriction of mod_rewrite where the Pattern can't be so close to the target file?
Try this:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+(.*)\.php [NC]
RewriteRule ^ /%1 [R=301,QSA,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f
RewriteRule ^([^/]+)/?$ $1.php [L]
First rule redirect the request to phpless page and the next internally to the php file itself.
Is this a restriction of mod_rewrite where the Pattern can't be so close to the target file?
Its not really a restriction, you just can't redirect the php file to non-php and then back to it as it generates a loop, so what we do is capture the request and redirect from there and then internally redirect to the file.
Unless of course like you have seen they have a different naming.

Remove .php extension with .htaccess

Yes, I've read the Apache manual and searched here. For some reason I simply cannot get this to work. The closest I've come is having it remove the extension, but it points back to the root directory. I want this to just work in the directory that contains the .htaccess file.
I need to do three things with the .htaccess file.
I need it to remove the .php
a. I have several pages that use tabs and the URL looks like page.php#tab - is this possible?
b. I have one page that uses a session ID appended to the URL to make sure you came from the right place, www.domain.example/download-software.php?abcdefg.
Is this possible? Also in doing this, do I need to remove .php from the links in my header nav include file? Should IE "support" be support?
I would like it to force www before every URL, so it's not domain.example, but www.domain.example/page.
I would like to remove all trailing slashes from pages.
I'll keep looking, trying, etc. Would being in a sub directory cause any issues?
Gumbo's answer in the Stack Overflow question How to hide the .html extension with Apache mod_rewrite should work fine.
Re 1) Change the .html to .php
Re a.) Yup, that's possible, just add #tab to the URL.
Re b.) That's possible using QSA (Query String Append), see below.
This should also work in a sub-directory path:
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]
Apache mod_rewrite
What you're looking for is mod_rewrite,
Description: Provides a rule-based rewriting engine to rewrite
requested URLs on the fly.
Generally speaking, mod_rewrite works by matching the requested document against specified regular expressions, then performs URL rewrites internally (within the Apache process) or externally (in the clients browser). These rewrites can be as simple as internally translating example.com/foo into a request for example.com/foo/bar.
The Apache docs include a mod_rewrite guide and I think some of the things you want to do are covered in it. Detailed mod_rewrite guide.
Force the www subdomain
I would like it to force "www" before every URL, so its not domain.example but www.domain.example/page
The rewrite guide includes instructions for this under the Canonical Hostname example.
Remove trailing slashes (Part 1)
I would like to remove all trailing slashes from pages
I'm not sure why you would want to do this as the rewrite guide includes an example for the exact opposite, i.e., always including a trailing slash. The docs suggest that removing the trailing slash has great potential for causing issues:
Trailing Slash Problem
Description:
Every webmaster can sing a song about the problem of the trailing
slash on URLs referencing directories. If they are missing, the server
dumps an error, because if you say /~quux/foo instead of /~quux/foo/
then the server searches for a file named foo. And because this file
is a directory it complains. Actually it tries to fix it itself in
most of the cases, but sometimes this mechanism need to be emulated by
you. For instance after you have done a lot of complicated URL
rewritings to CGI scripts etc.
Perhaps you could expand on why you want to remove the trailing slash all the time?
Remove .php extension
I need it to remove the .php
The closest thing to doing this that I can think of is to internally rewrite every request document with a .php extension, i.e., example.com/somepage is instead processed as a request for example.com/somepage.php. Note that proceeding in this manner would would require that each somepage actually exists as somepage.php on the filesystem.
With the right combination of regular expressions this should be possible to some extent. However, I can foresee some possible issues with index pages not being requested correctly and not matching directories correctly.
For example, this will correctly rewrite example.com/test as a request for example.com/test.php:
RewriteEngine on
RewriteRule ^(.*)$ $1.php
But will make example.com fail to load because there is no example.com/.php
I'm going to guess that if you're removing all trailing slashes, then picking a request for a directory index from a request for a filename in the parent directory will become almost impossible. How do you determine a request for the directory 'foobar':
example.com/foobar
from a request for a file called foobar (which is actually foobar.php)
example.com/foobar
It might be possible if you used the RewriteBase directive. But if you do that then this problem gets way more complicated as you're going to require RewriteCond directives to do filesystem level checking if the request maps to a directory or a file.
That said, if you remove your requirement of removing all trailing slashes and instead force-add trailing slashes the "no .php extension" problem becomes a bit more reasonable.
# Turn on the rewrite engine
RewriteEngine on
# If the request doesn't end in .php (Case insensitive) continue processing rules
RewriteCond %{REQUEST_URI} !\.php$ [NC]
# If the request doesn't end in a slash continue processing the rules
RewriteCond %{REQUEST_URI} [^/]$
# Rewrite the request with a .php extension. L means this is the 'Last' rule
RewriteRule ^(.*)$ $1.php [L]
This still isn't perfect -- every request for a file still has .php appended to the request internally. A request for 'hi.txt' will put this in your error logs:
[Tue Oct 26 18:12:52 2010] [error] [client 71.61.190.56] script '/var/www/test.peopleareducks.com/rewrite/hi.txt.php' not found or unable to stat
But there is another option, set the DefaultType and DirectoryIndex directives like this:
DefaultType application/x-httpd-php
DirectoryIndex index.php index.html
Update 2013-11-14 - Fixed the above snippet to incorporate nicorellius's observation
Now requests for hi.txt (and anything else) are successful, requests to example.com/test will return the processed version of test.php, and index.php files will work again.
I must give credit where credit is due for this solution as I found it Michael J. Radwins Blog by searching Google for php no extension apache.
Remove trailing slashes
Some searching for apache remove trailing slashes brought me to some Search Engine Optimization pages. Apparently some Content Management Systems (Drupal in this case) will make content available with and without a trailing slash in URLs, which in the SEO world will cause your site to incur a duplicate content penalty. Source
The solution seems fairly trivial, using mod_rewrite we rewrite on the condition that the requested resource ends in a / and rewrite the URL by sending back the 301 Permanent Redirect HTTP header.
Here's his example which assumes your domain is blamcast.net and allows the the request to optionally be prefixed with www..
#get rid of trailing slashes
RewriteCond %{HTTP_HOST} ^(www.)?blamcast\.net$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
Now we're getting somewhere. Lets put it all together and see what it looks like.
Mandatory www., no .php, and no trailing slashes
This assumes the domain is foobar.example and it is running on the standard port 80.
# Process all files as PHP by default
DefaultType application/x-httpd-php
# Fix sub-directory requests by allowing 'index' as a DirectoryIndex value
DirectoryIndex index index.html
# Force the domain to load with the www subdomain prefix
# If the request doesn't start with www...
RewriteCond %{HTTP_HOST} !^www\.foobar\.com [NC]
# And the site name isn't empty
RewriteCond %{HTTP_HOST} !^$
# Finally rewrite the request: end of rules, don't escape the output, and force a 301 redirect
RewriteRule ^/?(.*) http://www.foobar.example/$1 [L,R,NE]
#get rid of trailing slashes
RewriteCond %{HTTP_HOST} ^(www.)?foobar\.com$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
The 'R' flag is described in the RewriteRule directive section. Snippet:
redirect|R [=code] (force redirect) Prefix Substitution with
http://thishost[:thisport]/ (which makes the new URL a URI) to force
a external redirection. If no code is given, a HTTP response of 302
(MOVED TEMPORARILY) will be returned.
Final Note
I wasn't able to get the slash removal to work successfully. The redirect ended up giving me infinite redirect loops. After reading the original solution closer I get the impression that the example above works for them because of how their Drupal installation is configured. He mentions specifically:
On a normal Drupal site, with clean URLs enabled, these two addresses
are basically interchangeable
In reference to URLs ending with and without a slash. Furthermore,
Drupal uses a file called .htaccess to tell your web server how to
handle URLs. This is the same file that enables Drupal's clean URL
magic. By adding a simple redirect command to the beginning of your
.htaccess file, you can force the server to automatically remove any
trailing slashes.
In addition to other answers above,
You may also try this to remove .php extensions completely from your file and to avoid infinite loop:
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ $1.php [NC,L]
This code will work in Root/.htaccess,
Be sure to change the RewriteBase if you want to place this to a htaccess file in sub directory.
On Apache 2.4 and later, you can also use the END flag to prevent infinite loop error. The following example works same as the above on Apache 2.4,
RewriteEngine on
RewriteRule ^(.+)\.php$ /$1 [R,L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ /$1.php [NC,END]
The following code works fine for me:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
After changing the parameter AllowOverride from None to All in /etc/apache2/apache2.conf (Debian 8), following this, the .htaccess file just must contain:
Options +MultiViews
AddHandler php5-script php
AddType text/html php
And it was enough to hide .php extension from files
I've ended up with the following working code:
RewriteEngine on
RewriteCond %{THE_REQUEST} /([^.]+)\.php [NC]
RewriteRule ^ /%1 [NC,L,R]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_URI}.php [NC,L]
Here's a method if you want to do it for just one specific file:
RewriteRule ^about$ about.php [L]
Ref: http://css-tricks.com/snippets/htaccess/remove-file-extention-from-urls/
Try this
The following code will definitely work
RewriteEngine on
RewriteCond %{THE_REQUEST} /([^.]+)\.php [NC]
RewriteRule ^ /%1 [NC,L,R]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_URI}.php [NC,L]
Not sure why the other answers didn't work for me but this code I found did:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
That is all that is in my htaccess and example.com/page shows example.com/page.php
To remove the .php extension from a PHP file for example yoursite.example/about.php to yoursite.example/about: Open .htaccess (create new one if not exists) file from root of your website, and add the following code.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
To remove the .html extension from a HTML file for example yoursite.example/about.html to yoursite.example/about: Open .htaccess (create new one if not exists) file from root of your website, and add the following code.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
Reference: How to Remove PHP Extension from URL
Try this:-
RewriteEngine On
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]
I found 100% working Concept for me:
# Options is required by Many Hosting
Options +MultiViews
RewriteEngine on
# For .php & .html URL's:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteRule ^([^\.]+)$ $1.html [NC,L]
Use this code in Root of your website .htaccess file like :
offline - wamp\www\YourWebDir
online - public_html/
If it doesn't work correct, then change the settings of your Wamp
Server: 1) Left click WAMP icon 2) Apache 3) Apache Modules 4) Left
click rewrite_module
Here is the code that I used to hide the .php extension from the filename:
## hide .php extension
# To redirect /dir/foo.php to /dir/foo
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=301,L,NC]
Note: R=301 is for permanent redirect and is recommended to use for SEO purpose. However if one wants just a temporary redirect replace it with just R
Try
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [L]
If you're coding in PHP and want to remove .php so you can have a URL like:
http://yourdomain.example/blah -> which points to /blah.php
This is all you need:
<IfModule mod_rewrite.c>
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
</IfModule>
If your URL in PHP like http://yourdomain.example/demo.php than comes like
http://yourdomain.example/demo
This is all you need:
create file .htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
#RewriteRule ^([^\.]+)$ $1.html [NC,L]
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteCond %{THE_REQUEST} "^[^ ]* .*?\.php[? ].*$"
RewriteRule .* - [L,R=404]

Remove ".html" from URL via .htaccess for a WordPress website

Background information:
I've searched stackoverflow for a specific solution and couldn't find one that fixed my situation. Thanks in advance for any help you can offer. Your knowledge is appreciated.
I've decided to accept a contract to "convert" (in the client's words) a Joomla site into a WordPress site. Everything is going along smoothly, except that the Joomla site links to .html files, both in its navigation and in the content of 100+ posts.
Instead of going through each post one-by-one and updating the links or running a SQL command to remove ".html" from URLs, I've decided to put the pressure on .htaccess, with which I am somewhat comfortable.
What I'm trying to do ↓
In WordPress, I have custom permalinks enabled, and it is as follows:
/%category%/%postname%
Here's an example of what one of the old URLs in the posts looks like:
http://the-site.com/category/the-webpage.html
I need the htaccess file to tell the webserver to remove the .html so the user, after visiting "http://the-site.com/the-webpage.html" is instead sent to:
http://the-site.com/category/the-webpage
I'm setting up the page stubs to follow the file name of the Joomla pages, so http://the-site.com/category/the-webpage will work.
My question:
Can you help me discover the solution to removing .html from the URL when someone visits the site, even if the HTML file doesn't exist on the server?
Here's how the .htaccess file looked before I made changes:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
Here's the latest .htaccess file as of 5:35pm Eastern:
# BEGIN WordPress
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} \.html$
RewriteRule ^(.*)\.html$ $1 [R=301,L]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
The ↑latest .htaccess changes work. Thanks Tim!
This will work to force an external redirection to your new URLs, but this may not be ideal for your situation. I'm still trying to think if there's a way to keep the redirection internal and update the variable that WordPress uses to determine which page to serve up, but so far I haven't thought of anything that would work.
Entire .htaccess:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} \.html$
RewriteRule ^(.*)\.html$ $1 [R=301,L]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
You want to use a URL rewrite
RewriteEngine On
RewriteRule ^(.*)\.html$ $1
This should do it. It will rewrite a request to site.com/category/whatever.html to site.com/category/whatever. it shouldn't be dependent upon the requested file existing.
<Directory /var/www/category>
RewriteEngine on
RewriteRule (.*)\.html$ /category/$1
</Directory>
This is the format for apache2.conf or virtual host files. Not sure if you use the command in .htaccess. It's best to take care of it in the server conf, if you can, as that is only parsed once, on server startup, and htaccess is parsed on each request.

How to hide the .html extension with Apache mod_rewrite

I have a small number of static sites where I simply want to hide the .html extension:
the URL /foo fetches the static file /foo.html
the browser still displays the URL /foo
The client can then send out bookmarks in the style example.com/foo rather than example.com/foo.html.
It sounds very simple, and I've used mod_rewrite happily before (say with WordPress or for redirects), but this is proving much harder to crack that I thought. Perhaps I'm missing something really obvious, but I can't find a solution anywhere and I've been at it all day!
We run our own server, so this can go wherever is the best place.
Addendum
The solution checked below worked fine. Then after running the site awhile I noticed two problems:
all pages began to appear unstyled. I reloaded, cleared the cache, etc., but still no-style. I've had this trouble before, and can't locate the source.
There's a directory AND an HTML file named 'gallery', so the /gallery link shows a directory listing instead of the HTML file. I should be able to sort that one, but further tips welcome :-)
Try this rule:
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule !.*\.html$ %{REQUEST_FILENAME}.html [L]
This will rewrite all requests that can be mapped to an existing file when appending a .html.
The previous answers don't check if the requested path is a directory.
Here is the full rewrite condition which doesn't rewrite, if requested path is a directory (as stated by the original question):
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d # is not directory
RewriteCond %{REQUEST_FILENAME}\.html -f # is an existing html file
RewriteRule ^(.*)$ $1.html # rewrite index to index.html
To be SEO friendly and avoid double content, redirect the .html URLs:
# Redirects example.com/file.html to example.com/file
RewriteCond %{REQUEST_FILENAME} !-d # is not directory
RewriteCond %{REQUEST_FILENAME}\.html -f # is an existing html file
RewriteCond %{REQUEST_URI} ^(.+)\.html$ # request URI ends with .html
RewriteRule (.*)\.html$ /$1 [R=301,L] # redirect from index.html to index
If you need the same for scripts take a look here:
How can I use .htaccess to hide .php URL extensions?
The accepted solution do not works when the website is configured with a virtual host / document root.
There is the solution I used:
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME}.html -f
RewriteRule !.*\.html$ %{REQUEST_FILENAME}.html [L]
Look at this post http://alexcican.com/post/how-to-remove-php-html-htm-extensions-with-htaccess/ I haven't tried it yet but the demonstration seems pretty convincing.
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
Wow, I have seldom seen such an issue for which there exists so many "solutions" on the web, where people just throw up what "works for them" but for which few take time to read the documentation to figure out what it does. Many of the solutions given here don't work for virtual hosts, for example.
After much cross-referencing and reading, I want to contribute my own solution that "works for me". Hopefully it works for you, too. I didn't create it from scratch; I was inspired by all the other contributions (even though most of them did not "work for me" without modification).
RewriteEngine on
#if foo requested, return foo.html contents
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}\.html -f
RewriteRule ^(.*)$ $1.html [L]
#redirect foo.html to foo
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteRule ^(.+)\.html$ $1 [R,L]
The [R] flag by default does a temporary (302) redirect; if you want a permanent redirect, use R=301 in place of R.
To remove .html extension from .*.html requests, you can use the following script in root/.htaccess :
RewriteEngine On
RewriteBase /
#1) externally redirect "/file.html" to "/file"
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.html [NC]
RewriteRule ^ %1 [R=301,L]
#2) rewrite "/file" back to "/file.html"
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.*?)/?$ $1.html [NC,L]
the url /foo fetches the static file /foo.html
the browser still displays the url /foo
Apache can do this without mod_rewrite, see documentation:
Multiviews
The effect of MultiViews is as follows: if the server receives a request for /some/dir/foo, if /some/dir has MultiViews enabled, and /some/dir/foo does not exist, then the server reads the directory looking for files named foo.*, and effectively fakes up a type map which names all those files, assigning them the same media types and content-encodings it would have if the client had asked for one of them by name. It then chooses the best match to the client's requirements.
Source: http://httpd.apache.org/docs/current/content-negotiation.html
Here is an example which allows us to store the file on disk as:
foo.html.php
But in the browser, refer to it as
foo.html
To make this work for you, I think you would just need to modify it a bit to match your existing requests, and check for an actual file in place with the .html extension.
# These are so we do not need the .php extension
RewriteCond %{REQUEST_FILENAME} (\.xul|\.html|\.xhtml|\.xml)$',
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME}.php -f',
RewriteRule ^(.*)$ $1.php',

Multiple RewriteConds and RewriteRule Stacked Together

I have this apache rewrite rule:
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} mycompany.com
RewriteRule ^$ http://mycompany.com/login [L]
# we check if the .html version is here (caching)
RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
# no, so we redirect to our front web controller
RewriteRule ^(.*)$ index.php [QSA,L]
The only thing I can make sense of is if it's mycompany.com, then the script will redirect to http://mycompany.com/login. If not, then ...
I can't figure out already.
Any idea what does the above script say?
Something quite interesting, not easy to understand.
A google search on the comment texts inside the code gave interesting results: http://www.google.com/search?q=%22%23+we+check+if+the+.html+version+is+here+%28caching%29%22
Edit: if we look at the last lines and knowing that Symfony uses caching (it creates local files with .html extension in the same directories as the URL shows 'em) I can try to explain the lines here
If the requested url is something like http://yoursite.com/blabla/ we try to open an index.html file in that directory. If the file is not there, another cycle of rewriting will happen and the last Cond will be hit (where the file does not exist)
RewriteRule ^$ index.html [QSA]
If something more is in the url, like http://yoursite.com/blabla/blblbl, try to find a file blblbl.html
RewriteRule ^([^.]+)$ $1.html [QSA]
This is the collector of all urls that did not match any of the previous rules or the cached file did not exist:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]