What is the .htaccess/mod_rewrite solution for this redirect problem?

Tag: .htaccess , mod-rewrite Author: zhuangxuguo Date: 2010-08-23

(Please see important Additional information edited in near the bottom of question)

I'm trying to get the following url

http://www.example.co.uk/home/templates/cnb/fb_calendar/events/view/289

to redirect to

http://www.example.co.uk/home/index.php?option=com_content&task=view&id=574&Itemid=85&direct=view:289

I thought this would work

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^home/templates/cnb/fb_calendar/events/view/([^/\.]+)?$ http://www.example.co.uk/home/index.php?option=com_content&task=view&id=574&Itemid=85&direct=view:$1 [R=302,L]

but it didn't. The rule does not 'engage' at all - original url goes through unchanged. What am I doing wrong?

I'm including the whole .htaccess file below: the rule I'm talking about is the fourth one down. (The file was mostly generated by cpanel utility rather than by hand.)

RewriteEngine on

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^approve/([^/\.]+)/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=574\&Itemid\=85\&approve\=$1" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^disapprove/([^/\.]+)/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=574\&Itemid\=85\&disapprove\=$1" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^direct/([^/\.]+)/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=574\&Itemid\=85\&direct\=$1" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^home/templates/cnb/fb_calendar/events/view/([^/\.]+)?$ http://www.example.co.uk/home/index.php?option=com_content&task=view&id=574&Itemid=85&direct=view:$1 [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^uk/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=6\&Itemid\=7" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^inspirational/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=7\&Itemid\=8" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^gospel/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=1\&Itemid\=3" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^bible/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=1\&Itemid\=2" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^dab/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=14\&Itemid\=35" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^/?$ "http\:\/\/www\.example\.co\.uk\/home" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^abi/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=blogcategory\&id\=20\&Itemid\=37" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^anne/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=blogcategory\&id\=16\&Itemid\=55" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^ben/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=blogcategory\&id\=25\&Itemid\=56" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^catherine/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=blogcategory\&id\=22\&Itemid\=57" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^dave/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=blogcategory\&id\=26\&Itemid\=53" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^jan/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=blogcategory\&id\=21\&Itemid\=58" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^nick/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=blogcategory\&id\=23\&Itemid\=60" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^paul/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=blogcategory\&id\=18\&Itemid\=59" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^robbie/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=blogcategory\&id\=17\&Itemid\=61" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^roy/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=blogcategory\&id\=15\&Itemid\=54" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^ruth/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=blogcategory\&id\=19\&Itemid\=62" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^steve/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=blogcategory\&id\=14\&Itemid\=64" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^trevor/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=blogcategory\&id\=24\&Itemid\=63" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^jobs/?$ "http\:\/\/www\.ucb\.co\.uk\/vacancies" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^prayer/?$ "http\:\/\/www\.ucb\.co\.uk\/prayer" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^yousay/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=11\&Itemid\=31" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^christmasappeal/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=12\&Itemid\=32" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^luke/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=blogcategory\&id\=29\&Itemid\=68" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^juls/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=blogcategory\&id\=30\&Itemid\=71" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^tv/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=5\&Itemid\=6" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^canigetdab/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=14\&Itemid\=35" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^playlist\/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_wrapper\&Itemid\=74\/" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^books\/?$ "http\:\/\/www\.example\.co\.uk\/" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^bookcase\/?$ "http\:\/\/www\.example\.co\.uk\/" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^donate\/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=12\&Itemid\=32\/" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^haiti\/?$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=560\&Itemid\=78\/" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^easter$ "http\:\/\/www\.example\.co\.uk\/" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^social$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=568\&Itemid\=81" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^orgs$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=8\&Itemid\=28" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^cnb$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=574\&Itemid\=85" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^cnb\/login$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=574\&Itemid\=85\&login\=" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^noticeboard$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=574\&Itemid\=85" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^noticeboard\/login$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=574\&Itemid\=85\&login\=" [R=302,L]

RewriteCond %{HTTP_HOST} ^example.co.uk$ [OR]
RewriteCond %{HTTP_HOST} ^www.example.co.uk$
RewriteRule ^bagofhope$ "http\:\/\/www\.ucb\.co\.uk\/bagofhope" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^mp3stream$ "http\:\/\/example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=577\&Itemid\=87" [R=302,L]

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^posters$ "http\:\/\/www\.example\.co\.uk\/home\/index\.php\?option\=com_content\&task\=view\&id\=579\&Itemid\=88" [R=302,L]

-- Edit -- Additional information:

I've narrowed the problem down to the fb_calendar directory - if I use a directory with a random name instead of fb_calendar it works. So it must be something IN this directory that's causing the problem. There is another .htaccess file in this directory with the following contents:

<IfModule mod_rewrite.c>
   RewriteEngine on
   RewriteRule    ^$ app/webroot/    [L]
   RewriteRule    (.*) app/webroot/$1 [L]
</IfModule>

Is this causing the problem? I need a rewrite rule that will not be effected by any other .htaccess files/rewrite rules in folders on the path in the URL. How can I do this?

Maybe offtopic, but what's the purpose of that RewriteCond %{HTTP_HOST} ^.*$ ?
don't know but it's in all of the other 'rules' currently in the htaccess file, and they are working fine. Do you think this is the problem?
It's not a problem, but that RewriteCond will always be true (there's no benefit in having it, so you could remove it without changing anything). I personally don't see anything wrong with the rule you have, would you mind posting the rest of the .htaccess file?
You don’t need to escape any character in the substitution with a backslash.
Gumbo, thanks. The backslashes were added by cpanel which generates the code from a UI.

Best Answer

mod_rewrite will, by default, only use directives from a single .htaccess file per (internal) request, and the .htaccess file used will be the last one found to have mod_rewrite directives down your request path.

In this case, .../fb_calendar/.htaccess exists and contains directives, so they are used instead of the directives in your root.

Furthermore, note that none of the directives are inherited automatically, so doing something like the following will generate a 404, since directives are present, but the RewriteEngine was never turned on in the second file:

/.htaccess:

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ /index.php?here

/test/.htaccess:

RewriteRule ^ /index.php?there

Request -> http://example.com/test/non-existent-path

As it turns out, you can import rules from parent .htaccess files using the RewriteOptions directive:

RewriteEngine On
RewriteOptions inherit

Note that the parent rule set is imported after the existing rule set though, so in your case the path would be rewritten to .../fb_calendar/app/webroot/events/view/... before being processed by the rule in your root .htaccess file (and would therefore not match).

Your options in that case would be to either modify your rule to accommodate for that, or, perhaps more easily, you could just move your rule to the .../fb_calendar/.htaccess file and adjust it for being in that directory.

comments:

Useful info, thanks.

Other Answer1

RewriteRule ^home/templates/cnb/fb_calendar/events/view/([^/\.]+)?$ /home/index.php?option=com_content&task=view&id=574&Itemid=85&direct=view:$1 [R=302,L]

I just removed the http:// from the url it redirects to.

Works like a charm. Test it here:

http://manson.revora.net/home/templates/cnb/fb_calendar/events/view/1234

goes to

http://manson.revora.net/home/index.php?option=com_content&task=view&id=574&Itemid=85&direct=view:1234

Also, this rewrites the url in the address bar too, but since you added R=302 I take it that's what you wanted? And you don't need that first rule, as pointed out in the comments.

comments:

This fails in my particular circumstance - I think there is another .htaccess file in a directory on the target path that's interfering - please see Additional information I've edited at the end of my question. Thanks!
Yes, that .htaccess definitely interferes, for it sends all requests that end up in the fb_calendar folder to the subfolder /app/webroot/. I don't think it's possible to have a .htaccess rule that overwrites rules in subdirectories, that's just the way htaccess rules work.. You could change the htaccess in the fb_calender folder though but that might mean you're going to have to do that in a lot more folders.
Hmm... that's a bit annoying - I want it to rewrite the whole path as it is defined, not parse any other rules along the way. Powerful feature, but if that's not the behaviour you want then it's a big limitation.
Wait a second, I might be wrong. The request goes from base folder down to subfolders, but in the base folder you already say you want to rewrite fb_calender to something else. This shouldn't even hit your fb_calendar at all. Maybe there's something else interfering after all.