Reputation: 351
On a website, I have a .htaccess
file setup for rules on rewriting the url. All of my content pages are generated dynamically, so there is only one file, content.php
, and its basically generating the page based on a query parameter. The link structure of the site is then determined off of the main navigation.
So on content.php, its pulling the page from the database by looking at the URL. Behind the scenes, the URL would basically look like this:
www.website.com/content.php?page=my-page
However using rewrites, the url actually shows and displays like this:
www.website.com/my-page/
This works great, except for one issue I'm experiencing. You could pretty much add any directory you wanted before /my-page/, and the content for /my-page/ would still show. For example:
www.website.com/test1/test2/test3/my-page/
shows the same things as:
www.website.com/my-page/
If the actual link I want to use is: www.website.com/section/my-page/ how can I redirect any request that ENDS in /my-page/ to www.website.come/section/my-page/
I have tried using the following, but that ultimately ends up in an endless loop
RewriteRule (.*)/my-page/?$ http://www.website.com/section/my-page/ [L,R=301]
Upvotes: 2
Views: 177
Reputation: 6898
I had this problem, messed with regex for hours to no avail, following these answers. It turned out to be quite simple.
Turn off MutliViews
In short, in your server configuration, look for something like this...
Options -Indexes +FollowSymLinks +MultiViews
...and change it to this...
Options -Indexes +FollowSymLinks -MultiViews
Of course, that line may look very different, depending on your file. The point is, put a -
in front of MultiViews.
NOTE: If you don't see any symbols on that line, just remove
MultiViews
instead. Apache2 is all-or-nothing about use of symbols.
If you cannot (or don't want to) change server configuration, stick this line in your .htaccess
...
Options -MultiViews
That fixed it for me!
Upvotes: 0
Reputation: 785146
Replace this rule:
RewriteRule (.*)/my-page/?$ http://www.website.com/section/my-page/ [L,R=301]
By this rule:
RewriteRule ^(?!my-page/my-second-page)(?:.+?/)?(my-second-page)/?$ /my-page/$1/ [L,NC,R=302]
RewriteRule ^.+?/(my-page)/?$ /$1/ [L,NC,R=302]
Also test this in a new browser to avoid old 301 cache.
Upvotes: 1
Reputation: 470
Your rewrite (.*)
is saying anything/you/like/before/my-page will match, and you also have a 301 permanent redirect R=301
at the end of it which isn't needed.
In your .htaccess you can do the rewrites without the trailing slash:
RewriteEngine On
RewriteRule ^/section/([^/\.]+)$ /content.php?page=section&id=$1
RewriteRule ^/([^/\.]+)$ /content.php?page=$1 [L]
And then in content.php:
$page = (!isset($_GET['page'])) ? 'indexPage' : $_GET['page'];
switch($page){
case 'my-page':
// process request for /my-page
break;
case 'my-other-page':
// process request for /my-other-page
break;
case 'section':
$section_id = (!isset($_GET['id'])) ? 'NONE' : $_GET['id'];
// process /section/$section_id - i.e $section_id = my-section-1
break;
case 'indexPage':
// process request for index page, i.e /
break;
default:
// This should stop /the/anything/matching/my-page issue
header("HTTP/1.0 404 Not Found");
}
In the above php, $page
is set to indexPage
if $page
is empty or not set - and if $page
is set but doesn't match anything in the switch/case section it returns a 404 header.
$section_id
is handled the same way but set to NONE
if it isn't set or is empty; like the $page
variable, you can also send a 404 header if $section_id
is sent but doesn't match anything.
Upvotes: 0