Abstract

The approach described here is intended to create an overview of the hierarchy of a taxonomy & showing the related nodes. The layout of the nodes is defined by the associated view (see below). This could be useful e.g. for a list of all downloads of a page.

Example

Term 1 with Depth 0

  • node one of term 1, layout depending on view-settings
  • node two of term 1, layout depending on view-settings
  • etc., number depending on view-settings

Term 2 with Depth 0

  Term 3 with Depth 1, child of Term 2
    • nodes of term 3, layout depending on view-settings

Term 4 with Depth 0

  • nodes of term 4, layout depending on view-settings
  Term 5 with Depth 1, child of Term 4
    • nodes of term 5, layout depending on view-settings

Example: http://www.3dcenter.org/downloads

Steps to be taken

1. The Vocabulary

Create a new (optional: hierarchically) taxonomy or use an existing taxonomy. Remember its ID. It will be inserted in the PHP snippet shown in step 3.

2. The View

Create a new view for the nodes that use the vocabulary of step 1. As Argument Type for this view, set Taxonomy: Term Name. Remember the views name. It will be inserted in the PHP snippet shown below.

3. The php Snippet

This snippet is for Drupal 5 and views 1. For Drupal 6 and views 2 see comment of stone_d below.
Create new content or use existing content with PHP as input format. Then paste the following code and enter your values of step 1 & 2 in lines 2 & 5:

/* Enter the ID of the vocabulary which terms you want to show as headlines */
$vocabulary_id = "0";

/* Enter the name of the view that should show the nodes */
$view_name = "YOUR_VIEW";


/* Only edit if you know what you're doing */
$view = views_get_view($view_name);
if (!$view) {
    drupal_not_found();
    exit;
}
foreach(taxonomy_get_tree($vocabulary_id,0,-1,1) as $value) {
  print t("<div style='margin-bottom: 4em;'><h3>" . $value->name . "</h3>");
  print views_build_view('embed', $view, array($value->name), FALSE, $view->nodes_per_block);
  if ( taxonomy_get_children($value->tid) ) {
     print t("<div style='margin-left: 2em;'>");
     foreach( taxonomy_get_children($value->tid) as $child ) {
        print t("<h4 style='margin-top:2em;'>" . $child->name . "</h4>");
        print views_build_view('embed', $view, array($child->name), FALSE, $view->nodes_per_block);
      }
      print t("</div>");
  }
  print t("</div>");
}

Known issues

  • Currently the code only support terms of the first two depths (the modifications to support unlimited depths shouldn't be hard to do)
  • Hard coded CSS styles: I suggest to exchange them with your CSS classes.

Comments

mpeal’s picture

This snippet does exactly what I need, a list of events at each of several facilities.
I needed to make one important change.
As given, it displays the whole content of an event node. But the view associated with my block wants only a few fields to show.
In the line that starts print views_build_view('embed' I changes 'embed' to 'block'
The parameters for views_build_view are explained here: http://drupal.org/node/99721

stone_d’s picture

thank your for that snippet, u saved my day *hehe
I just trimmed it to drupal 6 with views2 and selected "formatted layout with rows" for my view - works perfect!

			/* Enter the ID of the vocabulary which terms you want to show as headlines */
			$vocabulary_id = "1";
			
			/*Enter the name of the view that should show the nodes */
			$view_name = "NAME_OF_YOUR_VIEW";

			foreach(taxonomy_get_tree($vocabulary_id,0,-1,1) as $value) {
			  print t("<div><h3>" . $value->name . "</h3>");
			  print views_embed_view($view_name, 'default', $value->name);
			  if ( taxonomy_get_children($value->tid) ) {
				 print t("<div>");
				 foreach( taxonomy_get_children($value->tid) as $child ) {
					print t("<h4 style='margin-top:2em;'>" . $child->name . "</h4>");
					print views_embed_view($view_name, 'default', $child->name);
				  }
				  print t("</div>");
			  }
			  print t("</div>");
			}	
shambler’s picture

stone_d - does the above actually work for Drupal 6? I get the terms as headers but underneath them I get all content rather than the content that has been assigned that term.

"View with taxonomy arguments, presented all on the same page: Terms as headlines, displayed hierarchically" - this is what I want - any other way of getting it? I am a Drupal newb unfortunately...

Wolfgang Reszel’s picture

I’ve added I third depth to the code and also made it to hide terms without content. It’s not elegant, but it works. I also remove the t() function from the tags.

<?php
/* Enter the ID of the vocabulary which terms you want to show as headlines */
$vocabulary_id = "5";

/*Enter the name of the view that should show the nodes */
$view_name = "VIEW_NAME";

$founddepth = 0;
$output = '';

foreach(taxonomy_get_tree($vocabulary_id,0,-1,1) as $parent) {
	$append1 = '';
	$append2 = '';
	$append3 = '';
	$viewcontent = views_embed_view($view_name, 'default', $parent->name);
	$viewchildren = taxonomy_get_children($parent->tid);
	$append1 = '<div class="h3"><h3>' . t($parent->name) . '</h3>';
	$append1 .= $viewcontent;
	if ( $viewchildren ) {
		$append2 = '<div class="h4">';
		foreach( taxonomy_get_children($parent->tid) as $child ) {
			$viewcontent = views_embed_view($view_name, 'default', $child->name);
			$viewchildren = taxonomy_get_children($child->tid);
			$append2 .= '<h4>' . t($child->name) . '</h4>';
			$append2 .= $viewcontent;
			if ( $viewchildren ) {
				$append3 = '<div class="h5">';
				foreach( taxonomy_get_children($child->tid) as $child2 ) {
					$viewcontent = views_embed_view($view_name, 'default', $child2->name);
					if ( !stristr($viewcontent,'view-content') ) continue;
					$append3 .= '<h5>' . t($child2->name) . '</h5>';
					$append3 .= $viewcontent;
				}
				$append3 .= '</div>';
			}
			if (!stristr($append3,'view-content')) $append3 = '';
			$append2 .= $append3;
		}
		$append2 .= '</div>';
	}
	if (!stristr($append2,'view-content')) $append2 = '';
	$append1 .= $append2.'</div>';
	if (!stristr($append1,'view-content')) $append1 = '';

	$output .= $append1;
}

print $output;
?>
epiphanymarketing’s picture

This is the first view I've been successful in getting to work on this site that's even close to what I need. However, it still does not correctly display the "child" categories (my vocabulary is made up of product categories and subcategories). It displays the correct contents of each specific category, but the presence of subcategories (and nodes within them) is ignored.

Any ideas?

Mercury500’s picture

Just in case you want your parent headers to link to their own taxonomy pages:

swap this line:


$append1 = '<div class="h3"><h3>' . t($parent->name) . '</h3>';

with

$append1 = '<div class="h3"><h3><a href="http://WEBSITE.COM/taxonomy/term/' . t($parent->tid) . '">' . t($parent->name) . '</a></h3>';

Anybody know how I can easily page this output? Lots-o-tags and this page is huge.

Thanks.

catachresis’s picture

Hey,

Thanks very much for this code -- I'm wondering how I should modify it to allow me to display users as opposed to nodes.

Cheers,
c;

rodibox’s picture

Hello
Someone tell me how to do this list but in Drupal 7
From already thank you very much.

spgd01’s picture

The following post provides some code less alternatives:
http://drupal.org/node/128085#comment-3452522

gaintsev’s picture

Thank you very much! You saved me a lot of time. :)