user2762748
user2762748

Reputation: 351

.htaccess Redirect/Rewrite rules

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

Answers (3)

CodeMouse92
CodeMouse92

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

anubhava
anubhava

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

Eilidh Fridlington
Eilidh Fridlington

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

Related Questions