1

I have all site pages in a subdirectory like this...

http://www.example.com/pages/myfile.php

I want the URL to look like this...

http://www.example.com/myfile

Where both the subdirectory called pages and the .php file extension are removed from the URL.

My latest (partial) attempt...

Options All -Indexes +FollowSymLinks

DirectoryIndex index.php

RewriteEngine On
RewriteBase /
RewriteCond %{DOCUMENT_ROOT}/pages%{REQUEST_URI}\.php -f [OR]
RewriteCond %{DOCUMENT_ROOT}/pages%{REQUEST_URI} -d
RewriteRule ^(.*)$ /pages/$1.php [NC,L]

However, this totally breaks DirectoryIndex. When I go to http://www.example.com/ or http://www.example.com/foo/, I get a 404 error instead of defaulting to index.php as defined by DirectoryIndex.

Apparently, it treats everything as a file name instead of recognizing the lack of a file name (directory) and attempting to use index.php.

I tried incorporating this solution into mine, it fixed the DirectoryIndex issue, but it broke everything else.

Is there a solution? Please include a detailed explanation within your answer so I can learn where/how I was going wrong.

Community
  • 1
  • 1
Sparky
  • 98,165
  • 25
  • 199
  • 285

1 Answers1

2

Try this in root .htaccess:

Options All -Indexes +FollowSymLinks
DirectoryIndex index.php

RewriteEngine On
RewriteBase /

# add a trailing slash if pages/<uri> is a directory
RewriteCond %{DOCUMENT_ROOT}/pages/$1 -d
RewriteRule ^(.*?[^/])$ %{REQUEST_URI}/ [L,R=302]

RewriteRule ^/?$ pages/index.php [L]

# skip all files and directories from rewrite rules below
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]

# if corresponding .php file exists in pages/ directory
RewriteCond %{DOCUMENT_ROOT}/pages/$1\.php -f
RewriteRule ^(.+?)/?$ pages/$1.php [L]

# route all requests to pages/
RewriteRule ^((?!pages/).*)$ pages/$1 [L,NC]
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • Specifically for that case I have that `# add a trailing slash ...` rule and I have tested this case as well. You should test in Chrome dev tool or test using curl. It will redirect `example.com/foo` to `example.com/foo/` not `example.com/pages/foo/`. – anubhava Jul 21 '15 at 19:49
  • 1
    You are correct. My browser cache was causing that last issue. – Sparky Jul 21 '15 at 19:51