Implementing Facets in Drupal
Now, the Drupal web site flew effortlessly past the gazillionth post probably way before Midsommar of 2001, but this does not make the content-finding problem every single bit less aggravating.
So, it's actually no surprise that the topic information architecture offers a fraction of the results of, say, page layout1 and one specific subject that returns just a few interesting speculative pages2 and a million quasi-false positives is faceted classification.
That of classification and actual information architecture is a well-known issue with all FL/OSS CMS, and one I've been talking about at conferences, but it actually seems so strange to me since Drupal is the one exception that proves the rule. Let me explain why I went and checked this in the first place.
Drupal comes with its own internal classification engine, dubbed the taxonomy module. The taxonomy module, among other distinct features3, deploys a very interesting syntax which allows direct-typing, URL-based retrieval of vocabulary terms:
taxonomy/term/[tids]/[depth]/[type]
where tids is either one term, or multiple terms separated by commas (for AND) or by +'s (for OR); depth is either 0 (default), a positive number for x levels of child terms, or 'all' for infinite levels of child terms and type is either 'page' (default) or 'feed' (for RSS)4.
That is, supposing you have a vocabulary containing the terms Gardening, Decorating and Tools whose numeric identifiers are respectively 16,20 and 32, you can write
<website-address>taxonomy/term/16
to retrieve all items pertaining to Gardening, and
<website-address>taxonomy/term/16+20
to retrieve all items pertaining to either Gardening or Decorating or, most interesting,
<website-address>taxonomy/term/16,32
to retrieve all Gardening items which are Tools. These URLs can be cleaned up by means of the Path module to provide meaningful recognition.
Given that the taxonomy module offers a rough but effective means to implement controlled vocabularies, taxonomies (hey) and thesauri 5 plus supports free tagging, we are in for some serious IA business.
If you design your vocabularies to act like facets, you actually have a very effective albeit plainly unfriendly faceted zooming interface via URLs.
So, the next logical step seems to provide a viable interface, links and menus and whatnot, to the facets and foci and then put in place logical checks to avoid, among other things, returning empty result sets.
I decided to try out a little experiment, mimicking the well known Facetmap wine demo up to a point6.
I built three distinct vocabularies for Type (table, sparkling, fortified), Color (red, white, ros), Region (Italy, France, Spain), which loosely come from Facetmap and some DCES consideration, and typed in some URLs.
You can check some terribly rough results of this, no additional props, plain Drupal, clicking the links below. Remember: appearance, text, styles, whatever, was not a priority.
All wines | Italian wines | Italian, fortified wines | Italian, fortified red wines
- 1. No pretense of scientificity here, but IA is a mere 4 pages result as opposed to the 20 pages of page layout
- 2. And the single most interesting one being referenced but off-site: see Thoughts about a Drupal drill down system
- 3. A powerful beast it is. A good starting point is the Drupal online Handbook entry Taxonomy, categories and classification schemes
- 4. You can find the original post here: http://drupal.org/node/39109#comment-71947. J. Epstein is the author of a new redesigned Category module.
- 5. A controlled vocabulary is basically a closed list of named subjects used for classification. A taxonomy is a (subject-based) classification that arranges the terms in the controlled vocabulary into a hierarchy (L. Garshol). A thesaurus, finally, extends a taxonomy allowing other statements to be made about the subjects. In the case of Drupal, this mostly means the ability to relate terms (RT) or provide synonyms (USE)
- 6. Meaning a) that I'm both no wine expert and personally not so interested in copying and pasting, so I made up all of the names and data and b) that I simply wanted to put up a quick and dirty test, so little data and no polishing here







