Search code examples
apache.htaccessmod-rewritejoomla

Redirect old URL's after relaunch with Joomla on Apache 2.4


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]

Solution

  • 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