Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pretty URLs for search pages

Tags:

routing

I really enjoy having "pretty" URLs (e.g. /Products/Edit/1 instead of /products.aspx?productID=1) but I'm at a loss on how to do this for pages that let you search by a large number of variables.

For instance, let's say you have a page that lets a user search for all products of a particular type with a certain name and near a specific address. Would you do this with really long "pretty" URLs

/Products/Search/Type/{producttype}/Name/{name}/Address/{address}

or just resort to using url params

/Products/Search?productType={producttype}&name={name}&address={address}
like image 444
Kevin Pang Avatar asked Sep 24 '08 18:09

Kevin Pang


3 Answers

This question is primarily about URL design and only incidentally about rewriting. Once you've designed your URLs to be cool, there are lots of ways to make them work including rewriting at the server level or using a web framework that does URL-based dispatch (I think most modern web frameworks do this these days).

Beauty is in the eye of the beholder, but I do agree with you that a lot of search urls are ugly. What makes them so? I think the primary thing that makes URLs ugly is cruft in the URL that doesn't add semantic meaning but is the result of an implementation detail, like (.aspx) or other extensions. My rule is that if a URL returns (X)HTML than it shouldn't have an extension, otherwise it ought to.

In the case of a search, the fact is that the standard search syntax does add meaning: it indicates that the page is a search, it indicates that the arguments are named and reorderable. The ugliness primarily comes from the ?&= characters, but really anything else you do will be to replace these same characters with more attractive characters like |-/, but at the cost of making the URL opaque to any software that wishes to parse it like a spider, a caching proxy server, or something else.

So think carefully about not using the standard syntax and be sure you have a good reason for doing it. I think in the case where your arguments have a natural order and must all be defined for the search to make sense and are compact, you could push it into the URL. For example, in a blog URL you might have:

/weblog/entries/2008
/weblog/entries/2008/11
/weblog/entries/2008/11/22

For a search defining the entries from 2008, nov 2008, and 22th of november 2008, respectively. Your URLs should be unique and unambiguous; sometimes people put in /-/ for missing search parameters, which I think is pretty compact. However, I would avoid pushing potentially long parameters, like a free-form text query, into the the URL. /weblog/entries/containing/here%20is%20some%20freeform%20text%20blah%20blah is not any more attractive that using the query syntax.

If you are going to use the standard query syntax, then picking argument names that are meaningful might improve the attractiveness, somewhat. products/search?description="blah", though longer, is probably better than products/search?q="blah". At this point it's diminishing returns, I think.

like image 119
Nick Avatar answered Sep 19 '22 04:09

Nick


You can get the "pretty" urls, but not through the prettiest of means..

You can set up your url to be something like:

/Products/Search/Type/{producttype}/Name_{name}/Address_{address}

Then a mod_rewrite rule something like:

RewriteRule ^Products/Search/Type/([a-z]+)(.*)?$ product_lookup.php?type=$1&params=$2 [NC,L]

This will give you 2 parameters in your product_lookup file:

$type = {producttype}
$params = "/Name_{name}/Address_{address}"

You can then implement some logic in your product_lookup.php file to loop through $params, splitting it up on the "/", tokenising it according to whatever is before the "_", and then using the resulting parameters in your search as normal, e.g.

// Split request params first on /, then figure out key->val pairs
$query_parts = explode("/", $params);
foreach($params as $param)
{
    $param_parts = explode("_", $param);
    // Build up associative array of params
    $query[$param_parts[0]] = $param_parts[1];
}
// $query should now contain the search parameters in an assoc. array, e.g.
// $query['Name'] = {name};

Having the parameters as "pretty" urls rather than POSTs enables users to bookmark particular searches more easily.

An example of this in action is http://www.property.ie/property-for-sale/dublin/ashington/price_200000-550000/beds_1/ - the user's selected params are denoted by the "_" (price range and beds) which can be translated internally into whichever param format you need, whilst keeping a nice readable url.

The code above is a trivial example without error checking (rogue delimiters etc in input) but should give you an idea of where to start.

It also assumes a LAMP stack (Apache for mod_rewrite and PHP) but could be done along the same lines using asp.net and an IIS mod_rewrite equivalent.

like image 45
ConroyP Avatar answered Sep 21 '22 04:09

ConroyP


The MVC (Model View Controller) framework is designed specifically to tackle this issue. It uses a form of url rewriting to redirect actions to pages and provides just the functionality you're looking for. It makes handling pretty urls a breeze.

With regard to the length of URLs, id still use pretty urls but a particularly long URL may be an indication that you may want to reconsider your grouping of the items, alter the classification if you will so Products/{NAME}/{Address} without intermediary url parts.

Examples of the MVC framework can be found at:

.Net - http://www.asp.net/mvc/

PHP - http://www.phpmvc.net/

Java - http://struts.apache.org/

like image 38
Wolfwyrd Avatar answered Sep 22 '22 04:09

Wolfwyrd