Newbie needs help with joomla site redirect

Topics: User Forum
Feb 4, 2010 at 9:47 PM
Edited Feb 4, 2010 at 9:51 PM

Hi All,

I am completely new to IIRF and, indeed, the whole SEF/SEO Rewrite/Redirect thing. I've done some research so I can at least (hopefully) talk intelligently on this subject! I sure appreciate any help anyone can offer.

My scenario is this--I've been placed in charge of a windows 2003 server (thus IIS 6) which is running a Joomla e-commerce web site. Integrated into Joomla is an "SEF" module called ARTIO which produces web search engine friendly links of the ugly/nasty joomla index.php?itemid=blahblah thing. Artio maintains a database of SEF Links, for example: ( and redirects them to actual Joomla Links. To complete the example: (,blah,blah. So far, so good... (oh, by the way, the server has your IIRF module installed... Artio support set up and configured IIRF as a prerequisite to setting up their SEF component into Joomla ... but I bet you already figured that!)

Now, after running good for more that 16 months, guess what? Our marketing guy wants to change the game again. If what I am understanding is correct, they want to do this:

* They want to make external requests for the original "ugly" (lets call it "non-sef") joomla link now 301 redirect to the search engine desirable sef link. So, to continue my example above, they want: (,blah,blah to redirect to It's like we're moving in circles here, in fact, at first I thought this would create a "loop" and might not be possible... but then I thought a little harder... maybe IIRF can take external http get/requests for the non-sef link and forward it to the sef link *FIRST* before joomla even "sees" what's going on. Then fall through and process the SEF link normally utilizing the "real" non-sef joomla link "internally only". I hope this makes sense... i think it does because if our little company wants to do it than others have to have already done it...

I guess this makes the original "real" joomla non-sef link no longer accessible ("directly") from the outside? 

Is it possible for me to hard code these original, joomla, non-sef links into the IIRF .ini file to point to designated SEF link(s) without "breaking" the original SEF Link? If so, would anyone be willing help me through an example? (such as my example above)? Is there an easier/better way of doing it besides editing the IIRF .ini file?

By the way, Artio only allows redirecting SEF links to joomla "real" links. You can't go the other direction ... so that's why I'm here at IIRF (the lower level -- where the real power is).

Thanks again,




Feb 4, 2010 at 10:55 PM
Edited Feb 5, 2010 at 11:55 AM

> Is it possible for me to hard code these original, joomla, non-sef links into the IIRF .ini file to point to designated SEF link(s) without "breaking" the original SEF Link?

Yes, this is very typical, and is probably a best practice.

Consider a simple example. 

You need 2 rules.  The first rule is a REDIRECT from the non-SEF to SEF url.  The second rule is a REWRITE from the SEF to non-SEF.  

RedirectRule  /index.php?arg1=([^&]+)&arg2=([^&]+)$     http://server/$1/$2         [R=301]
RewriteRule   /([^/]+)/([^/]+)$                         /index.php?arg1=$1&arg2=$2  [L]

Notice the target of the redirect should include the scheme, domain, and port (if any). The target of the rewrite must not include those things. (If you don't understand this, then read the IIRF documentation on the difference between rewrite and redirect.)  Also notie the [R=301]  modifier on the redirect rule - this is your 301 HTTP response code.   And the [L] modifer on the rewrite rule says "process no more rules".  This may or may not be appropriate in your scenario, but it usually is.

The order of the rules in the pair doesn't actually matter. I like to put the Redirect first in the ini file, but the order will not affect correctness of the behavior. An "ugly" URL that comes in will be redirected by IIRF , which means it never reaches joomla (but of course this approach is general and applies to any application backend. It's not limited to joomla). A "pretty" (SEF) URL comes in and is re-written, to the ugly one, where it can be handled by joomla.  

Of course, the regular expressions you use will vary, depending on what you want the external URLs to be.  If you examine the capturing groups - the things within parens in the patterns in each rule - you will see that they are similar-yet-different between the rules.  The capturing group for the first rule (The redirect) is ([^&]+).  The parens denote a capturing group - whatever matches this will be referencable by $1, $2, and so on.  Inside the parens is the pattern to capture.  It is one or more (denoted by the +) of a range of characters (denoted by the square brackets). Inside the  [ ] is the range definition - in this case ^& indicates "any character except ampersand".   

A similar capturing group is used in the rewrite rule, except the range is "any character except slash".  The reason for this difference is that the capturing group in the redirect rule must capture a query string parameter, which cannot include ampersand, while the capturing group for the rewrite rule must match a URL path segment, which cannot include slash.

I hope this clarifies things.


Feb 4, 2010 at 11:49 PM

I'm not totally "clear" but this helps a lot! THANK YOU MUCH!

I think it makes sense...

The redirect, as I read the docs, makes the transition to the new url VISIBLE to the requester (be it a user browser, search engine spider, whatever...?) and supplies an "explanation" as a code # but a rewrite performs the transition (or "forward" might be a better word) internally on the server only. The requestor never knows they've been "forwarded".

So we want the non-sef to sef to be a visible forward and we want the requester to know (or at least think) the sef link is the good one. This is why you said to use REDIRECT for non-SEF to SEF. But in the case of SEF to real joomla (non-SEF) we want that handled internally on the server only. We want the requester to think it [the sef link] is more "geniune" and we use REWRITE this time. Ya--I think I got it.

regarding syntax -> The left expression is the request and the right is the forward target. I take it the ^ is some sort of logistical NOT. In english, ([^&]+) IS () Capture, + String of Chars, ^& but not Ampersand.

Okay I do have one question before I go back and start experimenting with my first test case ...

Why do I need to address the REWRITE (SEF to non-SEF) at all? It would seem to me [though I haven't analyzed the .ini yet] there must aleady be some mechanism in place NOW that handles the SEF to non-SEF case by handing it joomla's artio... Why can't I just do the REDIRECT non-SEF to SEF case and then let the existing process handle SEF to non-SEF?

Should I put my custom link/rules at the top of the ini?

Thanks again ... this is neat (powerful) stuff!


Feb 5, 2010 at 12:26 AM

Existing INI:

RewriteCond %{URL} ^(/component/option,com) [NC,OR]   ##optional - see notes##
RewriteCond %{URL} (/|\.htm|\.php|\.html|/[^.]*)$  [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) /index.php [U]

########## Begin - Rewrite rules to block out some common exploits
## If you experience problems on your site block out the operations listed below
## This attempts to block the most common type of exploit `attempts` to Joomla!
# Block out any script trying to set a mosConfig value through the URL
RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
# Block out any script trying to base64_encode crap to send via URL
RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [OR]
# Block out any script that includes a <script> tag in URL
RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
# Block out any script trying to set a PHP GLOBALS variable via URL
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
# Block out any script trying to modify a _REQUEST variable via URL
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
# Send all blocked request to homepage with 403 Forbidden error!
RewriteRule ^(.*)$ index.php [F,L]
########## End - Rewrite rules to block out some common exploits

Feb 5, 2010 at 12:05 PM

RangerRik, I don't know if you need the RewriteRule.  If there's something in joomla that does this (artio?) without IIRF, then you may just be able to use the joomla capability for the rewrite piece, and use IIRF for the redirect piece, as you suggested.  Looking at your IIRF ini file, the line that reads:

RewriteRule (.*) /index.php [U]

... rewrites all requests to index.php. At first glance, this may seems to obliterate information.  Any url path in the incoming request is discarded when all requests are written to the constant index.php script.  But that index.php script is probably examining the HTTP_X_REWRITE_URL server variable, which gets set when the [U] modifier is used.  In other words, the original request is not obliterated, it is simply moved from the Url path to a variable, where it is accessible to joomla.

If this is the case, then you don't need the 2nd of the rules in the pair I suggested.  You don't need the RewriteRule, because you have a generic RewriteRule that handles every request. 

Putting the new RedirectRule at the top of the ini, is the right thing.  

Test it carefully, of course.


Feb 9, 2010 at 2:42 AM

Hi Cheeso -> I feel like I'm close but no joy yet.

I added the following to the top of my ini file:

RewriteLogLevel 3
RewriteLog e:\iirf\iirf_debug
RedirectRule /index.php?option=com_virtuemart&category_id=110&flypage=shop.flypage&manufacturer_id=0&page=shop.product_details&product_id=247 [R=301]

After reviewing the non-SEF and SEF links, I could find NO PATTERN or naming scheme "rule" which could explain a connection between all non-SEF to SEF links. As such, I believe I have to manually enter the links into the ini? (ie: no argument?) - Is there a limit to the number of redirects I can enter into the ini?

After trying my test redirect above, I could NOT get the redirect to occur. I only got the original non-sef link I was requesting in my browser... I checked and double checked I was entering the right link into the browser and the ini. So then, I enabled logging and had a look:


Fri Feb 05 23:26:16 - 3748 - New LogFile opened.

Fri Feb 05 23:26:16 - 3748 - ReadConfig: new log file name: 'e:\iirf\iirf_debug.3248.log'

Fri Feb 05 23:26:16 - 3748 - ReadConfig: WARNING: log file is under the ini file directory. Don't do this! Check the readme.

Fri Feb 05 23:26:16 - 3748 - ReadConfig: line 4: RedirectRule (rule 1) '/index.php?option=com_virtuemart&category_id=110&flypage=shop.flypage&manufacturer_id=0&page=shop.product_details&product_id=247' '' [R=301]

Fri Feb 05 23:26:16 - 3748 - ReadConfig: line 6: RewriteCond %{URL} ^(/component/option,com)



Fri Feb 05 23:26:16 - 3748 - DoRewrites

Fri Feb 05 23:26:16 - 3748 - DoRewrites: New Url: '/index.php?option=com_virtuemart&category_id=110&flypage=shop.flypage&manufacturer_id=0&page=shop.product_details&product_id=247'

Fri Feb 05 23:26:16 - 3748 - EvaluateRules: depth=0

Fri Feb 05 23:26:16 - 3748 - EvaluateRules: Rule 1 : -1 (No match)


Any Idea why why no match?

Thanks again!



Feb 10, 2010 at 12:46 AM


yes, the reason there is no match is because ? is a meaningful character in the regex language.  It is a quantifier, meaning "zero or one".  Appearing after the index.php in your pattern, it implies "zero or one p's", therefore it will match index.phoption=...  and index.phpoption=...

If you want to match a ?, then you need to escape it with a backslash in the test pattern.     index.php\?option...etc.

There is no limit to the number of rules you can put in the ini file.  But, I would suggest that you look a little more closely at the set of URLs you want to handle, for patterns.  There is likely a way to generalize the incoming URL requests.  For example, parameterize the product_id - I suppose not every request will use a product_id of 247.  If you need ideas on this, consult the examples included in the IIRF documentation.

good luck.