Forum Moderators: phranque

Message Too Old, No Replies

Redirect URL and all 'child' URL's below it

htaccess redirect

         

stemc

12:04 am on Jan 20, 2010 (gmt 0)

10+ Year Member



Hi there,

I wonder if someone could help me with a redirect please?

I'm already using the following .htaccess rules in order to remove index.php from the URL's that my CMS generates:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]

My website has an Events section, which can be found at mywebsite.com/events/. As well as the main events page, there's also hundreds of other pages within that URL structure, i.e. mywebsite.com/events/test-event/ mywebsite.com/events/test-event-2/ etc

So what I'd like to do is, redirect every web page that is or starts with mywebsite.com/events/ to a special message page, i.e. mywebsite.com/special-message/

I've tried using this:

# Re-direct away from Events pages
Redirect 301 /events/ [mywebsite.com...]

But I found that although it works great for the main events page, it doesn't for all the hundreds of other pages that start with myhwebsite.com/events/...

Any help on this would be appreciated.

Thanks,

Ste

g1smd

12:37 am on Jan 20, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Use a RewriteRule with [R=301,L] flags. Take advantage of the pattern matching you can use here.

Don't use Redirect or RedirectMatch. There are problems if you mix those with RewriteRule in the same .htaccess file.

stemc

2:29 pm on Jan 20, 2010 (gmt 0)

10+ Year Member



Hi there,

Thanks for your reply. I'll look into this but I fear it may be a bit over my head as it looks a bit too advanced for me.

Thanks.

jdMorgan

3:37 am on Jan 21, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I assume that you want *all* /events/<anything> URLs redirected to the (single) index page in /special-message/ then, since otherwise your rule "should have worked" ( by redirecting /events/<anything> to /special-message/<anything> ).

Please remember that we don't know anything about youe site, or what you expected or desired, so "it doesn't work" tells us little...

I'd suggest this, as a fix for your external redirect and a non-trivial speed-up of your internal rewrite:


RewriteEngine On
#
RewriteRule $1 ^events/ http://www.example.com/special-message/ [R=301,L]
#
RewriteCond $1 !^index\.php/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]

The modification to the second rule will eliminate two unnecessary file and directory-exists checks for every HTTP request received by your server. You may notice that your site "runs faster" with this simple change.

Jim

stemc

1:16 pm on Jan 23, 2010 (gmt 0)

10+ Year Member



Hi Jim,

Thanks for the reply and the .htaccess code, much appreciated.

I found that my original redirect would redirect mywebsite.com/events/<anything>/ to mywebsite.com/special-message/<anything>/ I was originally trying to forward to the home page of my website though, and was trying all sorts of combinations, so I'd take your word for it if you were to say that I probably had a syntax error in my original code. Thanks for the RewriteRule - it looks fairly 'simple', but I was looking at all sorts of example and couldn't get anything like this working myself. :)

I'm also really interested in what you suggest for the internal rewrite, as this is code that I just mindlessly copy and paste into the .htaccess file as a matter of habit when building websites using the ExpressionEngine.com CMS. By default, it inserts index.php into the URL of web pages, so you would have mywebsite.com/index.php/about/ instead of mywebsite.com/about/

I can't even remember where I got this original code from, but it looks to be via this page as there's a very similar example there: [expressionengine.com...]

I've just tried your alternative suggestion and it also works. I couldn't notice any speed improvements, but if you tell me that it's reducing requests, then that's got to be a good thing and would no doubt show more benefit during peak times of website traffic on my web server (I'm using a VPS with Apache 2.0.63 and PHP 5.2.10).

Thanks again,

Stephen

jdMorgan

11:21 pm on Jan 23, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Your original code used the mod_alias "Redirect" directive. As documented, "Redirect" uses prefix-matching, and any part of the requested URL-path not specified in the prefix is ignored for matching purposes, but appended to the substitution URL.

To demonstrate, these two mod_alias and mod_rewrite lines are functionally equivalent:


Redirect 301 /index. http://www.example.com/home.
RewriteRule ^index\.(.*)$ http://www.example.com/home.$1 [R=301,L]

Because mod_rewrite in .htaccess per-directory context is restarted after any rule matches and is invoked, the original expressions code does at least three file- and directory-exists check for every non-blank URL-path requested from your server. For a URL-path which does not resolve to a physical file or directory and which will therefore be handled by expressions, the code does two checks first, finds that the requested object does not exist as a physical file or directory, then rewrites to index.php, restarts from the top (all preceding rules are re-evaluated), does the file-exists-check again, and then, since the newly-rewritten "index.php" path does exist, it terminates processing this rule.

By manually excluding index.php from this check, you save at least one unnecessary call to the operating system's file-handler (and possibly an additional physical disk read if there's a lot of swapping going on).

By also excluding image, CSS stylesheet, and JavaScript file URL-paths, etc., you can greatly reduce the number of these unnecessary filesystem calls.

Jim

stemc

3:45 pm on Feb 15, 2010 (gmt 0)

10+ Year Member



Hi Jim,

Sorry for the delay in replying tot his one - I just wanted to say thanks for going through the explanation of how it works and why it's much more efficient on the server.

Thanks,

Stephen

stemc

5:56 pm on Mar 7, 2010 (gmt 0)

10+ Year Member



Hi Jim,

Just a quick follow-up. I was re-reading your post and you talked about excluding images, CSS and JS files, as well as index.php files, so I thought you might have been referring to both your code and the one in the link I posted?

If so, was this the .htaccess file you had in mind? (I've added in both your line and the equivalent line for images from my link above)


RewriteEngine On
RewriteCond $1 !^index\.php/
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]


I've either got it wrong or I'm being knit-picky, but given that this will be on every website I build with this CMS, I figured that it was something worth getting correct.

Thanks,

Stephen

jdMorgan

12:37 am on Mar 13, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



That should work. It's impossible for me to know what filetypes you use and how, but consider adding all filetypes that don't need to be handled by expressions engine to that exclusion list in your second rewritecond, keeping them in order of most-frequently-requested first. Things like .css, .xml, .txt, .rdf, and all document (e.g. .pdf and .doc) and media (video and audio) filetypes are candidates, as is the .php filetype itself -- in which case, you wouldn't need the first RewriteCond as it would be made redundant.

Jim