I have spent days trying to determine a clean way to do the following:

  1. Display a list of all top-level terms in a vocabulary with links to their child terms
  2. Upon clicking a link, be taken to a list of the children of those terms.
  3. Ad infinitum until the lowest-level term, for which a list of nodes tagged with that term will be displayed.

This seems like it would be pretty commonly-needed functionality but I can't find any solution that can handle arbitrary depth, particularly if not all term trees descend to the same depth.

An ideal solution would be one that uses Views 3, Contexts, EntityFieldQueries, or anything else that's well-supported in Drupal 7.

I'm able to do almost exactly what I want by making a simple view with three node:term relationships (term, term's parent, and term's parent's parent) and user those for sequential contextual filters. The only problem with this is that if there's a node with a termpath of too little depth, it gets listed as "uncategorized" and generates a dead link. Instead of doing that I'd like it to link to the next child term available.


4 Answers 4


I figured out a way to do this with only the Views module. It's not perfect — it doesn't generate a nice URL and breadcrumb with the taxonomy lineage the way that my solution for a taxonomy of a single depth would do.

Static Depth Browser

For a taxonomy of static depth (where all terms have the same depth of child terms), you would do the following:

  1. Create a view of nodes
  2. Add relationship to taxonomy term (Term)
  3. Add relationship to taxonomy term parent, accessible via Term (Parent)
  4. Add relationship to taxonomy term parent, accessible via Parent (Parent Parent)
  5. Repeat step 4 as many times as necessary for your taxonomy's depth.
  6. Add contextual filters for each one and make sure they're in the proper order. Set to display a summary when filter is not in URL.
  7. You'll probably want to override the breadcrumb and title for each filter.
  8. ???

Variable Depth Browser

For a taxonomy of variable depth (where some term trees have deeper levels of nesting than others), it's a bit more complex:

  1. Add a new top-level term (Foo) to your vocabulary and put all other terms under it.
  2. Create a view of terms with a page that displays term names
  3. Add contextual filter: Taxonomy term: Parent term
  4. When the default value is not in the URL, provide default value
  5. Set default value to your top-level term name (Foo)
  6. Specify validation criteria
    • Validator: taxonomy term
    • Criteria: your vocabulary name
    • Filter value type: Term name converted to term ID
  7. Click the "+Add" button at the top of the Views panel to add an Attachment to the view.
  8. Add to this attachment only (override) Relationship: Taxonomy term: Content with term
  9. Add to this attachment only (override) display: fields: node titles linked to nodes, and remove (from this attachment only!) display: fields: term name
  10. Add to this attachment only (override) contextual filter: Taxonomy term: Name
  11. When filter value is not available, provide default value: Raw value from URL: Path component: 2 (or more if your Page path has >1 component)
  12. Attachment settings: Attach to: [name of the page display you just made]
  13. ???
  14. PROFIT

Screenshots of Views' UI for reference: enter image description here

  • Nicely done! Upvoting both the question and your answer -- it seems like fairly common thing to need to do and your solution is better than anything I found while initially trying to answer.
    – aendra
    Commented Jul 31, 2012 at 8:28
  1. Create a view of the type Taxonomy
  2. Add a contextual filter of the type Taxonomy term: Parent term
  3. Set Provide default value and keep it as fixed. give the Term ID of the top Parent term
  4. Add Taxonomy term ID as field and Exclude it from display
  5. Add a Taxonomy Term Name click on out put this field as a link; give the link as "path-you-set-in-view/[tid]"
    Note : You should uncheck "Link this field to its taxonomy term page"

When you visit the view page you would see the children of the top parent; as per the example you would get:

  • term1
  • term2

When you click on term1 you would get the children. Until you reach term1.1.1. You wont get any result if you click on term1.1.1 yet. To achieve that we need to create one more view block in the above view.

  1. Add a Block
  2. Remove the existing contextual filter and field
    Note : When you remove them make sure you select the This Page (Over Ride) from the drop down at the top next to For other wise the fields and contextual filters you created in the page would also be gone.
  3. Add a new contextual filter Taxonomy term: Term ID
  4. Add a relationship Taxonomy term: Content with term
  5. Add the Content Title and you use the relationship from the drop down at the top.
  6. Save the view and go back to the Page we create (This is important other wise you would not be able to complete the next step
  7. Add a field in the FOOTER OR HEADER
  8. Select "Global: View area" from the list and select the block we created from the drop down View to insert while you are there check Inherit contextual filters so that we can pass the value from this view to the block as well
  9. Check Display even if view has no result so that when this view does not show the result the block would still be shown

Save the view, and you are done.

  • I followed the clear explanation of Mohammed Shameem. Thank you, works perfect !!
    – Steven
    Commented Jan 22, 2013 at 20:19

I think what you're wanting is Views Tree, a contrib module that uses Views to construct a tree of taxonomy terms.

(Give me a second and I'll write a quick how-to on using it view tax fields)

Apparently that module has an issue preventing it from working with taxonomy terms. Boo.

That said, I found the following code which seems to do what you're wanting (you can make it display/hide elements through some pretty rudimentary jQuery code):


// The ID of the taxonomy vocabulary for which you'd like to create a nested list
$vid = 10;

$depth = 0;
$num_at_depth = 0;
$tree = taxonomy_get_tree($vid);

print "<ul class=\"menu\">\n<li>";
foreach ($tree as $term) {
  $diffdepth = 0;
  if ($term->depth > $depth) {
    print "\n<ul>\n<li>";
    $depth = $term->depth;
    $num_at_depth = 0;
  if ($term->depth < $depth) {
    $diffdepth = $depth - $term->depth;
    while ($diffdepth > 0) {
      print "</li>\n</ul>\n";
    $depth = $term->depth;
  if (($term->depth == $depth) && ($num_at_depth > 0)) {
    print "</li>\n<li>";
  print l($term->name, 'taxonomy/term/' . $term->tid);
print "</li>\n</ul>\n";

Via "Nested category lists with links to pages".

  • I have enabled that module and tried experimenting with it and I have two problems: 1. I suspect it just gives you a flat list, not a multi-paged browsing experience and 2. I can't get it to work. A how-to would be most helpful.
    – beth
    Commented Jul 6, 2012 at 14:14
  • Updated answer. Apologies, apparently Views Tree has an open issue re: using taxonomy terms. Alternative answer posted.
    – aendra
    Commented Jul 6, 2012 at 14:43
  • That appears to give a simple nested list rather than a sequentially-paged browser.
    – beth
    Commented Jul 6, 2012 at 14:53
  • @beth -- Would it suffice if I wrote some jQuery that shows/hides elements of that list when parent/child items are clicked?
    – aendra
    Commented Jul 9, 2012 at 14:56
  • I don't want it to be JavaScript dependent.
    – beth
    Commented Jul 9, 2012 at 14:58

If you just want to have a set of dynamic taxonomy-browsing pages, then I would go the following way, requiring 3 Views + Taxonomy Display module which allows you to use Views to display contents of taxonomy/term/% pages:

  1. Top Level Terms - list terms whose parent is null
  2. Mid Level Terms - list terms whose parent is NOT null. No result: display View #3
  3. Nodes with Terms - list nodes tagged with terms.

As Views 1 and 2 will probably be themed in a similar way, you might consider merging them as displays into one View - it'd be manageable more easily.

I have successfully used that approach for my taxonomy. It fortunately was homogenous at each level - a given branch ended with either leaves (nodes) or branches (terms), but not both. If this would be a limitation, please test it first.

Of course this is a "pseudo-code". You'd want to set up validations and filters, and a nice, logically-looking pathauto patterns to reflect the structure.

Not the answer you're looking for? Browse other questions tagged or ask your own question.