Forum Moderators: phranque

Message Too Old, No Replies

RewriteRule customization

customizing my RewriteRule based on the querystring

         

flamingsole

2:45 am on Apr 13, 2007 (gmt 0)

10+ Year Member



So hi. I've lurked around here for a little while, but this is my first post. I'm very new to RewriteRules, and have been stumbling through thus far based on tutorials and the questions others have asked and had answered. I'm rewriting the following: example.com/?category=value1&page=value2&subpage=value3 into example.com/category/page/subpage/. I've finally got this part working, and if there's no subpage present in the querystring, it goes up to the page.

My question, then, is this. Is it possible to create my rewrite in such a way that I can have a default category, and a default page, so that if these values are not present in the querystring they display what I want? For example, example.com/main/home/ would, instead, redirect to example.com/.

I hope I'm being descriptive enough with this. As it now stands, here is the relevant portion of my .htaccess:

RewriteRule ^/*index.php - [L]
RewriteRule ^index/(.+)/(.+)/(.+)/$ index.php?category=$1&page=$2&subpage=$3 [nc] [OR]
RewriteRule ^index/(.+)/(.+)/(.+)$ index.php?category=$1&page=$2&subpage=$3 [nc] [OR]
RewriteRule ^index/(.+)/(.+)/$ index.php?category=$1&page=$2 [nc] [OR]
RewriteRule ^index/(.+)/(.+)$ index.php?category=$1&page=$2 [nc]

Thanks so much.

[edited by: jdMorgan at 2:53 pm (utc) on April 13, 2007]
[edit reason] Example.com [/edit]

jdMorgan

2:52 pm on Apr 13, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



> I'm rewriting the following: example.com/?category=value1&page=value2&subpage=value3 into example.com/category/page/subpage/.

You are in fact doing the reverse: You are rewriting the static (non-querystring) URL, when requested by the client browser to the dynamic (querystring) URL needed to call your script. Mod_rewrite works during the URL-to-filename-translation phase of the Apache API, just after a request is received from the client, and before entering the content-handling phase where page content is returned or scripts are executed (to create and return page content). My purpose here is not to be picky, but rather to clarify; Understanding the terms and the 'direction' of a rewrite is critical to success.

With that, you should be able to come up with additional rules to detect missing 'pieces' of the requested URL, and simply insert a fixed name/value pair specifying the default page in the query string; I can't tell you exactly how to do that without a complete list of URLs that you intend to rewrite, but an example might be:


RewriteRule /*index\.php - [L]
RewriteRule ^index/([^/]+)/([^/]+)/([^/]+)/?$ /index.php?category=$1&page=$2&subpage=$3 [L]
RewriteRule ^index/([^/]+)/([^/]+)/?$ /index.php?category=$1&page=$2&subpage=[b]default_page[/b] [L]

Note that the last two lines correct and completely replace your four -- by making the trailing "/" optional, the redundant lines have been eliminated.

I replaced the ambiguous and inefficient ".+" patterns with "[^/]+" patterns meaning, "match one or more characters not equal to a slash." This is much faster than letting the regex parser try to find all the boundaries between URL-path-parts without any guidance, and prevents unexpected matches on longer URLs as well.

In case it's not clear, the new patterns say, "match 'index' followed by a slash, followed by one or more non-slash characters, followed by a slash, etc. This allows the requested URL-path to be evaluated in a single left-to-right pass, rather than making the parser repeatedly try to find a 'best fit' using a pattern that says "anything (including a slash) followed by a slash, followed by anything (including a slash), followed by a slash, etc.

The pattern using multiple ".+" subpatterns will initially match everything in the requested URL into the first subpattern, fail on matching the subsequent subpatterns, take one character out of the first subpattern match, try to match it into the second subpattern, fail again, and repeat, one character at a time, until it has correctly apportioned the characters in the requested URL into the subpatterns. This can easily take *hundreds* of trials, and is horribly inefficient.

I also removed the [nc] and [OR] flags -- Those weren't right and won't be needed.

For more info on the whole subject of rewriting static to dynamic URLs, see this thread [webmasterworld.com] from our Apache forum library [webmasterworld.com].

Jim