As I understand it, Drupal is supposed to check the web root for any URLs it doesn't recognize, to see if it's a non-Drupal file on disk. Also, Apache is supposed to assume that anything without a file extension is a request for whatever.html, correct?

Here's what I'm trying to achieve: a user requests mysite.com/FOO, Drupal doesn't find any path/alias for FOO, and thus turns it over to Apache. Apache doesn't see a file extension, and thus looks for a file called FOO.html (which exists) and serves up that file.

If I request mysite.com/FOO.html, the file is returned just fine. I'm just trying to make it so that people can access FOO.html by simply requesting /FOO, since you can't trust the user to type in the full URL. (And because it looks nicer in a print ad.)

I'm guessing that there's some .htaccess magic that needs to happen, but I haven't been able to come up with the right trick. I think that Drupal passes to Apache, which doesn't find /FOO, then the .htaccess file punts the request to Drupal's index.php, which returns the Drupal 404 page.


If the file exists serve it.

  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}\.html -s
  RewriteRule .* %{REQUEST_URI}\.html [L,T=text/html]

You'll need to put it above this inside your .htaccess file.

  # Pass all requests not referring directly to files in the filesystem to
  # index.php. Clean URLs are handled in drupal_environment_initialize().
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteRule ^ index.php [L]

You can't pass the request back to apache once you've passed it to Drupal. The code above will hit the .html file first if it exists.

To do exactly what you want, you can set the 404 handler inside of drupal to a custom page; that page could then check to see if the file exists and use that. Config page for 404: admin/config/system/site-information. The handler would use something like this

$path = substr(request_uri(), strlen($GLOBALS['base_path'])) . '.html';
if (file_exists($path)) {
  echo file_get_contents($path);
// OR this, not sure.
return drupal_not_found();
  • Thanks, @mikeytown2. The .htaccess solution almost works for me! I removed the DOCUMENT_ROOT variable, and changed REQUEST_URI to REQUEST_FILENAME, and then it works if the case entered matches the case of the filename. However, the NC flag doesn't seem to have an effect on the RewriteRule. If I enter /FOO (and my file is called FOO.html) then it works, but not if I enter /foo. Any way to make Apache serve up FOO.html if the request was lowercase?
    – eljefejb
    Mar 18 '15 at 18:48
  • Reading up on the nocase flag seems like there is no way to do it easily :/
    – mikeytown2
    Mar 18 '15 at 19:19

You can use the Redirect Module (https://www.drupal.org/project/redirect) to create custom URL redirections.


This is what finally worked for me:

In httpd.conf :

<IfModule mod_rewrite.c>
RewriteMap lc int:tolower
RewriteMap uc int:toupper

In .htaccess :

#-- is it a code with letters only?

# lower-case only
RewriteCond %{REQUEST_URI} ^/[a-z]+$ [OR]
# upper-case only
RewriteCond %{REQUEST_URI} ^/[A-Z]+$
# convert to upper-case and redirect to corresponding file
RewriteRule (.*) ${uc:$1}\.html [L]

This allows the little PHP snippet inside the appropriate file to make a tally mark in the tracking database, before redirecting the user to the desired landing page within the actual website. I know, Drupal can track hits on a specific URL, but I'm dealing with a legacy system from our pre-Drupal days. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.