Forum Moderators: phranque

Message Too Old, No Replies

Conditional Mod Rewrite

Rewriting URL based on existence of variables in querystring

         

dcampbell

4:10 pm on Mar 1, 2007 (gmt 0)

10+ Year Member



Hi folks

I'm attempting to rewrite a url dependent on whether the event variable is found in the querystring. If the event variable is not found the url would be written as such:

www.somesite.com/december/index.html

If the event variable was found the url would be written as:

www.somesite.com/december/example-event.html

The script below is what I currently have, the first rewrite condition works fine, however I can't seem to get the latter one to work - it brings up a 404.

Any guidance would be greatly appreciated.

Thanks

Options +FollowSymlinks
RewriteEngine on
RewriteRule ^(.+).html $1.php [nc]

RewriteCond %{REQUEST_URI}!^/event.*
RewriteRule ^(.+)/index.html month-template.php?month=$1 [L]

RewriteCond %{REQUEST_URI} ^/event.*
RewriteRule ^(.+)/(.+).html event-template.php?month=$1&event=$2 [L]

jdMorgan

4:57 pm on Mar 1, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



REQUEST_URI contains only the URL, not the query string data appended to the URL. You will need to use the QUERY_STRING variable for your intended purpose.

If the URL example.com/widgets.php?color=green is requested from your server, the variables will contain:

HTTP_HOST == example.com
REQUEST_URI == /widgets.php
QUERY_STRING == color=green
URL as seen by RewriteRule == widgets.php (no leading slash in .htaccess context)

Also, be careful with start- and end-anchoring the query string pattern. Because of the start-anchor (carat), a RewriteCond pattern of "!^color=green" will match only if the requested query string does not *begin* with "color=green". If the name-value pair can "float" in the query string, then a pattern of "!&?color=green&?" is better; It avoids anchoring problems, and it won't be fooled if the query string contains "xcolor=green" or "color=greener" because it requires that if a character precedes or follows the desired name/value string, it must be an ampersand.

Jim

dcampbell

12:32 am on Mar 2, 2007 (gmt 0)

10+ Year Member



Thanks JD, I'll give it a go :)

dcampbell

11:34 am on Mar 2, 2007 (gmt 0)

10+ Year Member



OK, I now have the following:

Options +FollowSymlinks
RewriteEngine on
RewriteRule ^(.+).html $1.php [nc]

RewriteCond %{QUERY_STRING}!&?event=.*&?
RewriteRule ^(.+)/index.html month-template.php?month=$1 [L]

RewriteCond %{QUERY_STRING} &?event=.*&?
RewriteRule ^(.+)/(.+).html event-template.php?month=$1&event=$2 [L]

Unfortunately the second rewrite condition still brings up a 404.

Thanks

jdMorgan

2:05 pm on Mar 2, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Your patterns are "too loose" -- The first rule will immediately rewrite *any* .html file in the .htaccess file's directory or in *any* subdirectory below to the same-named .php file, defeating the last two rules. You'll need to re-arrange the rules or specify a more-specific pattern or add RewriteConds for the first rule; Otherwise, the next two rules will never see any ".html" requests.

I'd suggest using more-specific patterns for all of your rules -- This will both prevent unexpected rewriting and speed up processing. For example, if the URLs to be rewritten by the third rule are always in the form /<directory>/file.html then a better approach would be:


RewriteCond %{QUERY_STRING} &?event=[^&]*&?
RewriteRule ^([^/]+)/([^.]+)\.html$ event-template.php?month=$1&event=$2 [L]

Here, we use negative-matching to specifically look for the *end* of the query- and URL-parts that we want to match into the three back-references. Note also that literal periods which are not in [groups] should be escaped (e.g. "\.html").

Jim