Forum Moderators: phranque
I'm new to this forum, and also to mod_rewrite, and am needing to pick your brains on this one.
I have the following code which performs a redirect, then rewrite based on a two RewriteMap directives; the only difference between the two mapfiles are that in one file, the key & values have been reversed.
RewriteCond %{THE_REQUEST} ^GET\ /test\.asp\?meta=([a-z-]+)\ HTTP
RewriteRule ^test\.asp$ http://localhost/${level1-1:%1}? [R=301] RewriteRule ^([a-z-]+)/?$ test.asp?meta=/${level1:$1 In level1 I have 'horses ho', and in level1-1 I have 'ho horses'.
Obviously it's impossible to have the variables preceding the relevant backreferences in either of the RewriteRules, which is why I had to stick to creating two mapfiles in this instance.
I've been looking at internal functions both for RewriteCond and RewriteMap but can't find anything that would be remotely useful for me.
Could someone point out to me where I'm going wrong and how I can consolidate these two mapfiles?
Thanks in advance
James
If not, then I'd like to point out that you could use a rewritemap or a direct internal rewrite to call a script, passing it several parameters including the 'order' and/or "action" (i.e. rewrite or redirect), and let that script look up the 'transform' in either direction from a single text file or even from your main database if you have one, and then do the redirect or rewrite (actually an 'include' of the desired resource) as requested.
Jim
No this certainly isn't the case, Jim.
The purpose of this rewrite is to convert a URL such as 'test.asp?meta=ho' to '/horses'. What I'm getting myself confused on is how I can utilise the same mapfile for both redirect and rewrite RewriteRules, since the position of the pattern and substition values (in my example, at least) aren't consistent:-
*Redirect*: RewriteRule ^test\.asp$ [localhost...] [R=301]
*Rewrite*: RewriteRule ^([a-z-]+)/?$ test.asp?meta=/${level1:$1}
If the pattern and substitution strings were placed in the same order in both RewriteRules, then I'd have no problem using the same mapfile. The underlying issue, however, is that between RewriteRules, I'm declaring both keys and values as variables.
Other entries in the RewriteMaps include
*level1* - 'sheep sh' 'geese ge' 'dogs do' 'pigs pi'
*level1-1* - 'sh sheep' 'ge geese' 'do dogs' 'pi pigs'
It's probably worth mentioning at this stage, that I'm actually not using Apache for this; I'm using the ISAPI Rewrite 3 plugin for IIS 5, so I'm fairly limited as to what scripting I can perform.
A rewrite does not do that.
It works the other way. It accepts a URL request for example.com/horses and fetches content from the internal server filepath at /test.asp?meta=ho - the difference between a URL 'used on the web' and a filepath 'used inside the server' is key here.
It works in conjunction with a redirect that accepts URL requests for example.com/test.asp?meta=ho and tells the user to make a new request for the URL example.com/horses instead.
I am clear as to how mod_rewrite works in this respect; 'test.asp?meta=ho' exists on the internal server (and also on our live site, which I'm demoing by invoking the proxy passthrough feature) and have successfully redirected (301 from 'test.asp?meta=ho' to '/horses') and rewritten (accepts a request for '/horses' and fetches the content located at 'test.asp?meta=ho'.
That is why I suggest writing a script for use either during the URL-to-filename-translation API phase by calling it as a RewriteMap, or during the content-handler phase by passing (rewriting) all requests to that script.
In the first case, you can pass the script a variable (see RewriteRule's [E] flag) telling it which way you want to translate (long to short, or short to long) in addition to the 'key' received in the client-requested URL. It can use a pre-defined data table to do the requested operation, and return the required looked-up value.
In the second case, you just pass (internally rewrite) *all* requests to a PHP or PERL script, and let it determine whether a redirect is needed. If not, it can either 'include' the requested resource (file), generate the requested content, or invoke another script, as desired.
My main point is that if you have a two-column lookup table with 'long' and 'short' value columns, and you want to call it with key=short and get answer=long, and you also want to call it with key=long and get answer=short, then a 'text' RewriteMap won't work for you. You'll need to write your own script which can use any lookup table you like in any format you like to look up short from long or long from short (assuming there are no unresolvable collisions in short values such as ho=horse and ho=house.)
Jim
I was actually having a look through the RewriteRule documentation a little earlier and was surprised to see that there was no predefined internal function that would solve this issue.
I've had a word with the devs here, and it's not too much of a problem creating two almost idenitical lookup tables (just reversed key/values) as they would be system generated. Will having two lookup tables for this purpose, as opposed to a central one, have a significant performance effect on lookups? FYI, we will have around 5000 keys/values
Regards
James
You should also look into the script method, and see whether that would allow you to integrate/centrailze this data in your main CMS database (if you use one), which would likely make administration a whole lot easier. You can use RewriteMap to call a simple PERL script to open your database and get the needed data, for example, returning it for use by the RewriteRule.
I advise you to take a step back, look at the big picture, and don't rush to implementation by focusing on one directive in one module for 'the' solution... Don't rush from 'requirements specification' to implementation, in other words.
And do beware of the potential for 'irresolvable collisions' with this plan as I mentioned above, between "ho=horse" and "ho=house."
Jim