Hi! Perhaps this is already possible (although I couldn't figure out how to do it).

Support I have a taxonomy as:

Vocab
--term a
----term b
----term c
--term d

I would like to be able to have it display a tree like listing of the nodes grouped by term (duplication would be fine if a node is in more than one category). Ideally, I would be able to root the display either at the vocabulary (ie, show all nodes associated with a term in this vocabulary, grouped by term) or at one of the terms (ie, using the tree above, show me everything associated with terms a, b, and c, but not d).

Am I missing something? If not, could this be added?

Thanks,
Ricky

CommentFileSizeAuthor
#16 lineage_1.module6.2 KBkarens
#12 lineage_0.module5.84 KBkarens
#11 lineage.module5.61 KBkarens

Comments

pukku’s picture

(One thing I forgot to mention: I wrote a module that sort of does this already — if this isn't already possible, I can definitely upload the module, although I'm completely baffled by the Views code that I've read so far, so I don't know that I could integrate it and provide a patch...)

merlinofchaos’s picture

This is now in CVS HEAD. You'll need to clear your cache after an update in order to see the new trees.

merlinofchaos’s picture

Status: Active » Fixed
Anonymous’s picture

Status: Fixed » Closed (fixed)
jorditr’s picture

Version: » 6.x-2.x-dev
Status: Closed (fixed) » Active

I would like to add that feature to 4.6. I know you're not supporting it anymore but could anyone give me some clue to where should I upgrade the 4.6 module to allow that kind of output?

jorditr’s picture

Category: feature » support

I've changed it from feature request to support request.

merlinofchaos’s picture

Status: Active » Closed (won't fix)

The magic is in views_handler_filter_tid_by_voc()

See views_taxonomy.inc

Sorry I don't have more to offer right now.

RobRoy’s picture

Version: 6.x-2.x-dev » 4.7.x-1.x-dev
Status: Closed (won't fix) » Active

Has this been backported to DRUPAL-4-7? I have a view with Tax Term as an argument and the Summary, sorted ascending just lists all terms out without a tree structure.

- term a
- term a1
- term a2
- term b

instead of

- term a
-- term a1
-- term a2
- term b

Am I just goofing on something?

RobRoy’s picture

I'm talking about when you access the view without the term argument. The arg summary just lists all the terms straight out. Is this something I should be doing in theme_views_summary_VIEWNAME()?

RobRoy’s picture

Here is what I have that is working. There is total redundancy in calling the get filtered tree, but I needed an easy way to get depths for possibly filtered hierarchially structure taxonomy terms. If we could get the weights on the first round that would be awesome. Merlin, you have a tip for me to look in Views for a possible (unlikely as Views is scary) patch?


function phptemplate_views_summary_docs($view, $type, $level, $objects, $args) {
  $trees = array();
  foreach ($objects as $object) {
    $term = taxonomy_get_term($object->tid);
    $term->num_nodes = $object->num_nodes;
    $term->letter = $object->letter;
    // Really we could avoid this stupid taxonomy_get_filtered_tree() if we 
    // just got the term depth on our own or from Views.
    $items[$term->vid][$term->tid] = $term;
  }

  foreach ($items as $vid => $item) {
    $output .= theme('views_taxonomy_tree', taxonomy_get_filtered_tree($vid, 0, -1, NULL, $items[$vid]), $view, $level);
  }

  return $output;
}

function taxonomy_get_filtered_tree($vid, $parent = 0, $depth = -1, $max_depth = NULL, $allowed_terms = array()) {
  static $children, $parents, $terms;
  $allowed_tids = array_keys($allowed_terms);
  $depth++;

  // We cache trees, so it's not CPU-intensive to call get_tree() on a term
  // and its children, too.
  if (!isset($children[$vid])) {
    $children[$vid] = array();

    $result = db_query(db_rewrite_sql('SELECT t.tid, t.*, parent FROM {term_data} t INNER JOIN  {term_hierarchy} h ON t.tid = h.tid WHERE t.vid = %d AND t.tid IN ('. implode(', ', array_fill(0, count($allowed_tids), '%d')).') ORDER BY weight, name', 't', 'tid'), array_merge(array($vid), $allowed_tids));
    while ($term = db_fetch_object($result)) {
      $term->num_nodes = $allowed_terms[$term->tid]->num_nodes;
      $term->letter = $allowed_terms[$term->tid]->letter;
      $children[$vid][$term->parent][] = $term->tid;
      $parents[$vid][$term->tid][] = $term->parent;
      $terms[$vid][$term->tid] = $term;
    }
  }

  $max_depth = (is_null($max_depth)) ? count($children[$vid]) : $max_depth;
  if ($children[$vid][$parent]) {
    foreach ($children[$vid][$parent] as $child) {
      if ($max_depth > $depth) {
        $terms[$vid][$child]->depth = $depth;
        // The "parent" attribute is not useful, as it would show one parent only.
        unset($terms[$vid][$child]->parent);
        $terms[$vid][$child]->parents = $parents[$vid][$child];
        $tree[] = $terms[$vid][$child];

        if ($children[$vid][$child]) {
          $tree = array_merge($tree, taxonomy_get_filtered_tree($vid, $child, $depth, $max_depth));
        }
      }
    }
  }

  return $tree ? $tree : array();
}

function phptemplate_views_taxonomy_tree($terms, &$view, $level) {
  $last_depth = -1;
  $output = '';
  foreach ($terms as $term) {
    // Adjust the depth of the <ul> based on the change
    // in $term->depth since the $last_depth.

    if ($term->depth > $last_depth) {
      $output .= "\n" . '<ul>' . "\n";
    }
    else if ($term->depth < $last_depth) {
      for ($i = 0; $i < ($last_depth - $term->depth); $i++) {
        $output .= '</li>' . "\n";
        $output .= '</ul>' . "\n";
      }
    }
    else {
      $output .= '</li>' . "\n";
    }
    // Display the $term.
    $output .= '<li>';
    $output .= views_get_summary_link($view->argument[$level]['type'], $term, $view->real_url)  .' ('. $term->num_nodes .')';
    
    // Reset $last_depth in preparation for the next $term.
    $last_depth = $term->depth;
  }

  // Bring the depth back to where it began, -1.
  if ($last_depth > -1) {
    for ($i = 0; $i < ($last_depth + 1); $i++) {
      $output .= '</li>' . "\n";
      $output .= '</ul>' . "\n";
    }
  }
  return $output;
}
karens’s picture

StatusFileSize
new5.61 KB

I found a way to do this using another module and your code, but it still needs testing and debugging. Start with Earl's taxonomy_lineage module (http://www.drupal.org/project/lineage). The module does not have an install file, so you'll need to manually add the lineage table. That module makes a depth field available in your view and also allows you to sort by heirarchy.

I've altered the module a bit to include your theme functions, so substitute the attached module for the one available on the project page.

Then create a view and add a field for the depth, and sort it by taxonomy lineage. Add a taxonomy argument and set it up to display a summary view of the argument.

You should get a nice nested taxonomy tree listing.

karens’s picture

StatusFileSize
new5.84 KB

Did a bit more clean up work on this to be sure it would not intervene in other kinds of summaries and fix the link when a vocabulary argument precedes the taxonomy argument. I also played around with views_handler_filter_tid_by_voc() to see if there was a way to do this without using the lineage table, and there is, but it is *much* slower. Using the lineage table a page with 100 terms and several hundred related nodes loaded very quickly, and the nested summary list works great.

I don't know if Earl wants these themes added to the lineage module, but that seemed to be the logical place to put them. If he likes and it seems useful, I can make this into a patch for the lineage module. I didn't move this issue to that queue because this is where people will be looking if they are trying to create a nested taxonomy tree listing in views.

merlinofchaos’s picture

I will look into this a little later, depending on how much time I have (working my way through the queue) -- however, I want to comment that this may be a good candidate for a bonus pack plugin.

karens’s picture

I'd be glad to make it into a bonus pack plug in, but I haven't quite figured out what that means. I don't think it would be a plug-in, exactly, since I don't want to control the output on the final view, just on the summary views. I'd want people to be able to use all the existing options for the final view and they won't have those options if I make this a plugin. I could create a patch for views_bonus.module to add the themes in there, but I don't know if that's what you meant.

I may not be understanding how you want to use the bonus pack, so I'll wait for some enlightenment. I can adjust whichever way you want to go :-)

karens’s picture

Follow up after more testing. This method work great so long as you choose a table or list view and add in the title and depth fields, but won't work for full page or teaser views which don't pull those fields into the query, so I need to figure out a slightly different way to do this to ensure the needed fields are getting brought in.

karens’s picture

StatusFileSize
new6.2 KB

For whatever it's worth (pending a decision about where this really belongs) here's the version that now works with teasers as well as table views.

pukku’s picture

Hi! Although I started this off, I ran into time constraints, and am only now able to start playing around with this. Supposing I have nodes which are categorized according to two different vocabularies: say, "meeting" vs. "conference call", and also according to the group that I'm referring to: "group a", "group b", "group c". How would I set up a view where I pass as an argument "group a", then get back a list grouped by "meeting" and "conference call" -- the idea is to use insert_view to put these inline into a page...

So, I would like to do [view:view_name==group a], and have it be replaced with:

conference call
- group a conference call minutes 1
- group a conference call minutes 2
meeting
- group a meeting minutes

or, if I do [view:view_name==group b], I get

conference call
- group b conference call minutes 1
meeting
- group b meeting minutes 1

Is this possible? I'm having problems specifying which vocabulary I want to sub-categorize, and well as actually getting it to display the list inline, rather than as clickable links to descend.

Thanks,
Ricky

merlinofchaos’s picture

pukku: What you want to do is problematic I think. Using taxonomy that many different ways is kind of difficult for Views unfortunately. It seems straightforward on the surface, but the query generation gets a little complex, and that's one area that Views is known to break down and not do things quite right.

I'm not really sure you can do it that way.

merlinofchaos’s picture

Version: 4.7.x-1.x-dev » 6.x-2.x-dev
Status: Active » Closed (fixed)