This is more or less a Question about redirecting [301] on Apache, but having some other required rules in place for the Joomla CMS.
We relaunched a Website with Joomla 3. The old one was some other CMS. Now we would like to redirect [301] the old URL's to the new location.
The Problem seems to be that this is not working. I would like to have one solution that could fit all our cases (almost 300).
Here are some examples that we like to redirect (old => new):
/index.php?CID=1 => /
/index.php?CID=2&Kat=1$ => /
/index.php?CID=3&Kat=2&PID=100 => /new/path
/old/path/file.extention => /new/file/path
/old/page.html => /new/page
/show_image.php?image=123456.jpg&text=Very%20Long%TEXT => /new/path/location
/show_image.php?image=654321.jpg&text=Very%20Long%TEXT => /other/path/location
I tried already some RewriteRules like:
RewriteRule ^/index\.php\?CID=1$ http://%{HTTP_HOST}/ [R=301,L]
OR
RedirectMatch 301 ^/index\.php\?CID=1$ /
For some URLs the RedirectMatch version works but not for most of them, specially not all URLs stating with /index.php , I assume because this is the entry Point for Joomla.
Is there a way to redirect concrete URL's including the once the starts with /index.php before the Joomla RewriteRule become active?
RewriteEngine is On and working with the default htaccess coming with Joomla: SEF URLs and URL-Rewrite is enabled.
Please give me some hint in the right direction. Thx
Here is the default Joomla .htaccess config if you don't know it:
<IfModule autoindex>
IndexIgnore *
</IfModule>
Options +FollowSymlinks
Options -Indexes
RewriteEngine On
RewriteCond %{QUERY_STRING} base64_encode[^(]*\([^)]*\) [OR]
RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
RewriteRule .* index.php [F]
RewriteBase /
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{REQUEST_URI} !^/index\.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L]
In the meanwhile I find the solution myself and I want to share it here with you.
So the main problem here is that if you want to redirect URLs with a Query String you can't use Redirect or RedirectMatch. You have to use a Rewrite Rule with a Query String Rewrite Condition, there is no way around it. And that means you will end up with at least two lines for some of the URLs (not what I hoped), for a URL without any query string it will work within one line.
So here are the some solutions for the given examples:
/index.php?CID=1 => /
/index.php?CID=2&Kat=1$ => /
Because only the Query String is different but the file/path (index.php) and the destination (/) is the same we can concatenating the Rewrite Condition with a OR Flag:
RewriteCond %{QUERY_STRING} ^CID=29$ [OR]
RewriteCond %{QUERY_STRING} ^CID=2&Kat=1$
RewriteRule ^index\.php$ /? [R=301,L]
Impotent here is the ? in the last line. If you only put a / to the destination apache will redirected to e.g. /?CID=29 not just /
For any other example with a query string you have to do it very similar
/index.php?CID=3&Kat=2&PID=100 => /new/path
/show_image.php?image=123456.jpg&text=Very%20Long%TEXT => /new/path/location
/show_image.php?image=654321.jpg&text=Very%20Long%TEXT => /other/path/location
Those are solves as follows:
RewriteCond %{QUERY_STRING} ^CID=3&Kat=2&PID=100$
RewriteRule ^index\.php$ /new/path? [R=301,L]
RewriteCond %{QUERY_STRING} ^image=123456\.jpg&text=Very%20Long%TEXT$
RewriteRule ^show_image\.php$ /new/path/location? [R=301,L]
RewriteCond %{QUERY_STRING} ^image=654321\.jpg&text=Very%20Long%TEXT$
RewriteRule ^show_image\.php$ /other/path/location? [R=301,L]
Please note the you have to add the ? at the end as well.
For all Examples without a query string this works as usual. Here some of the examples that I was mentioning:
/old/path/file.extention => /new/file/path
/old/page.html => /new/page
We just redirect it like this:
RewriteRule ^old/path/file\.extention$ /new/file/path [R=301,L]
RewriteRule ^old/page\.html$ /new/page [R=301,L]
Some additional remarks:
Because the Rewrite Rule pattern (the original file/path) or the Rewrite Condition pattern (in this case the Query String) is always interpreted as a regular expression where a doth means "any character" I put always a \ in front of it, so I really only match the correct file or query string and not some similar files like "index-php" or "index7php" etc. If you have other RegEx specific characters (e.g. + or *) you should do the same.
I also had some Rewrite Rule Pattern where the original URL include some space, this will cause a 500 Error but could be solved very simple by putting the hole Rewrite Rule Pattern within double quotes.
This will worked under Apache 2.4. and I hope it could help!
For all of you how wants to place this into the .htaccess file coming with Joomla you should put it before RewriteBase /
This is where the custom redirects should be