views:

478

answers:

9

Imagine you had a group of product categories organized in a nice tree hierarchy and you wanted to provide hackable urls to browse these. You could do something like this

/catalog/categorya/categoryb/categoryc

You could then quite easily figure out which category you should list the products for (note that the full URL is needed since you could have categories with the same name but at different locations in the hierarchy)

Now what would be a good approach to add product information in that as well? To give you an example, you wanted to display the product Oblivion for this category

/catalog/games/consoles/playstation/adventure

It's tempting to just add the product at the end of the url

/catalog/games/consoles/playstation/adventure/oblivion

but the moment you do so you loose the ability to know if its category or a product which is called oblivion. I personally feel that not being forced to add a suffix such as .html

/catalog/games/consoles/playstation/adventure/oblivion.html

would be the nicest solution and using some sort of prefix, such as

/catalog/games/consoles/playstation/adventure/product:oblivion

You could also add some sort of trigger like

/catalog/games/consoles/playstation/adventure/PRODUCT/oblivion

not as nice either and you would (even though its very unlikely it would be a problem) restrict yourself from having a category called product

So far a suffix solution looks like the most user-friendly approach that I can think of from the top of my head but I'm not fond of having to use an extension

What are your thoughts on this?

+1  A: 

Those all look fine (except for the one with the colon).

The key is what to do when they guess wrong -- don't send them to a 404 -- instead, take the words you don't know and send them to your search page results for that word -- even better if you can spell check there.

Lou Franco
+1  A: 

If you see the different pieces as targets then the product itself is just another target. All targets should be accessable by target.html or only target.

catalog/games/consoles/playstation.html
catalog/games/consoles/playstation

catalog/games/consoles/playstation/adventure.html
catalog/games/consoles/playstation/adventure

catalog/games/consoles/playstation/adventure/oblivion.html
catalog/games/consoles/playstation/adventure/oblivion

And so on to make it consistent.

My 5 cents...

Stefan
A: 

@Lou Franco yeah either method needs a sturdy fallback mechanism and sending it to some sort of suggestion page or seach engine would be good candidates

@Stefan the problem with treating both as targets are how to distinguish them (like I described). At worst case scenario is that you first hit your database to see if there is a category which satisfies the path and if it doesn't then you check if there is a product which does. The problem is that for each product path you will end up making a useless call to the database to make sure its not a category.

@some yeah a delimiter could be a possible solution but then a .html suffix is more userfriendly and commonly known of.

TheCodeJunkie
+8  A: 

Deep paths irk me. They're hideous to share.


/product/1234/oblivion --> direct page
/product/oblivion --> /product/1234/oblivion if oblivion is a unique product, 
                  --> ~ Diambiguation page if oblivion is not a unqiue product. 

/product/1234/notoblivion -> /product/1234/oblivion

/categories/79/adventure -->  playstation adventure games
/categories/75/games -->  console games page
/categories/76/games -->  playstation games page 
/categories/games --> Disambiguation Page. 
Otherwise, the long urls, while *seeming* hackable, require you to get all node elements right to hack it. Take php.net
php.net/str_replace -->  goes to 
  http://nz2.php.net/manual/en/function.str-replace.php

And this model is so hackable people use it all the time blindly.

Note: The .html suffix is regarded by the W3C as functionally meaningless and redundant, and should be avoided in URLs.

http://www.w3.org/Provider/Style/URI

Kent Fredric
I agree, don't use .html or other extensions for text/html responses.
lubos hasko
I agree, unless the default representation of the resource is not text/html. Also, following the recommendation of http://www.w3.org/Provider/Style/URI#remove will break pretty much every fix for transparent PNGs in IE6. Sometimes suffixes are a necessary evil.
system PAUSE
A: 

i like /videogames/consolename/genre/title" and use the amount of /'s to distinguish between category or product. The only thing i would be worried about multi (or hard to distinguish) genre. I highly recommend no extension on title. You could also do something like videogames(.php)?c=x360;t=oblivion; and just guess the missing information however i like the / method as it looks more neat. Why are you adding genre? it may be easier to use the first letter of the title or just to do videogame/console/title/

acidzombie24
+5  A: 

Lets disect your URL in order to be more DRY (non-repetitive). Here is what you are starting with:

/catalog/games/consoles/playstation/adventure/oblivion

Really, the category adventure is redundant as the game can belong to multiple genres.

/catalog/games/consoles/playstation/oblivion

The next thing that strikes me is that consoles is also not needed. It probably isn't a good idea to differentiate between PC's and Console machines as a subsection. They are all types of machines and by doing this you are just adding another level of complexity.

/catalog/games/playstation/oblivion

Now you are at the point of making some decisions about your site. I would recommend removing the playstation category on your page, as a game can exist across multiple platforms and also the games category. Your url should look like:

/catalog/oblivion

So how do you get a list of all the action games for the Playstation?

/catalog/tags/playstation+adventure

or perhaps

/catalog/tags/adventure/playstation

The order doesn't really matter. You have to also make sure that tags is a reserved name for a product.

Lastly, I am assuming that you cannot remove the root /catalog due to conflicts. However, if your site is tiny and doesn't have many other sections then reduce everything to the root level:

/oblivion
/tags/playstation/adventure

Oh and if oblivion isn't a unique product just construct a slug which includes it's ID:

/1234-oblivion
Chris Lloyd
+1  A: 

One problem is that your user's notion of a "group of product categories organized in a nice tree hierarchy" may match yours. Here's a google tech talk by David Weinberger's "Everything is Miscellaneous" with some interesting ideas on categorizing stuff:

http://www.youtube.com/watch?v=x3wOhXsjPYM

ja
A: 

My humble experience, although not related to selling games, tells me:

  • editors often don't use the best names for these "slugs", they don't chose them wisely.
  • many items belong (logically) to several categories, so why restrict them (technically) to a single category?

Better design item urls by ids, (i.e. /item/435/ )

  • ids are stable (generated by the db, not editable by the editor), so the url stands a much bigger chance at not being changed over time
  • they don't expose (or depend on) the organization of the objects in the database like the category/item_name style of urls does. What if you change the underlying design (object structure) to allow an item to belong to multiple categories? the category/item urls suddenly won't make sense anymore; you'll change your url design and old urls might not work anymore.

Labels are better than categories. That is to say, allowing an item to belong to several categories is a better approach than assigning one category to each item.

hasen j
A: 

the problem with treating both as targets are how to distinguish them (like I described). At worst case scenario is that you first hit your database to see if there is a category which satisfies the path and if it doesn't then you check if there is a product which does. The problem is that for each product path you will end up making a useless call to the database to make sure its not a category.

So what? There's no real need to make a hard distinction between products and categories, least of all in the URI, except maybe a performance concern over an extra database call. If that's really such a big deal to you, consider these two suggestions:

  1. Most page views will presumably be on products, not categories. So doing the check for a product first will minimize the frequency with which you need to double up on the database lookups.
  2. Add code to your app to display the time taken to generate each page, then go out to the nearest internet cafe (not your internal LAN!) with a stopwatch. Bring up some pages from your site and time how long each takes to come up. Subtract the time taken to generate the page. Also compare the time taken to generate one-database-lookup pages vs. two-database-lookup pages. Then ask yourself, when it takes maybe 1-2 seconds total to establish a network connection, generate the content, and download the content, does it really matter whether you're spending an extra 0.05 second or less for an additional database lookup or not?

Optimize where it matters, like making URLs that will be human-friendly (as in Chris Lloyd's answer). Don't waste your time trying to shave off the last possible fraction of a percent.

Dave Sherohman