Views2 and Taxonomy

We encourage users to post events happening in the community to the community events group on https://www.drupal.org.
harrisben's picture

This is my first post to the Drupal Dojo, so please forgive me if I sound like a noob. This is only because I am :)

I'm working on a Drupal6 site where I have created a vocabulary, the terms of which are product categories. The terms I've used have a nested structure and there are certain terms that have no nodes, only other terms, within them.

I can create a view that returns all products grouped by taxonomy term (http://www.cibus.co.th/pricelist) - that's the easy part.

My problem/s:

  1. I cannot make views sort the terms I am grouping by correctly based upon the nested structure because terms have the same weight at different levels.

  2. I cannot make views display terms that contain no nodes.

I can't see a way to do this, so does this mean I'm going to need to write something myself (which I understand how to do conceptually...)?

Please let me know if there are any further details I can provide that might help to understand, but I would appreciate your opinions and/or advice.

Thanks in advance.

Comments

Progress Report

harrisben's picture

I've been looking at this more and am proceeding in the hope that it is possible to call a view (with arguments) from php. Can someone tell please tell me if this can be done so I can save time researching and start building the queries myself?

Using my poor php skills I have been able to build a list of my taxonomy terms by weight, respecting the depth, with some classes attached to them so that I can theme them later on. While the following may seem elementary-level to many of you, this is my first coding attempt (my expertise is understanding systems, not necessarily designing them myself).

<?php
$vid
= 1// Set the vid to the vocabulary id of the vocabulary you wish to list the terms from
$parent = 0;
$depth = -1;
$max_depth = 1;
$terms1 = taxonomy_get_tree ($vid, $parent, $depth, $max_depth);
foreach (
$terms1 as $term1) {
  print
'<div class="term-top">' . $term1->name . '</div>';
  if (
count ($terms2 = taxonomy_get_children ($term1->tid, $vid))) {
    foreach (
$terms2 as $term2) {
      print
'<div class="term-middle">' . $term2->name . '</div>';
      if (
count ($terms3 = taxonomy_get_children ($term2->tid, $vid))) {
        foreach (
$terms3 as $term3) {
          print
'<div class="term-bottom">' . $term3->name . '</div>';
        }
      }
    }
  }
}
?>

Now I plan to:

  1. Should it be possible to call a view (with arguments) from php, insert what is needed at each loop to print the view for the respective term id, which will be the argument my view will accept. I have already themed the view so I really hope this is possible.

  2. Use jquery ui to make each term and the respective children collapsible.

  3. Hopefully ajaxify the loading of each term's view so that the initial load of the page isn't so hefty.

Feedback is welcome.

More Progress

harrisben's picture

It's a productive night here!

I have completed my next task, calling a view using the term id as an argument, as follows. I had to put the term id into an array as $arg accepts an array, but could just reuse it for the entire thing. I'm open to pointers on how this could be more efficient.

<?php
$vid
= 1// Set the vid to the vocabulary id of the vocabulary you wish to list the terms from
$parent = 0;
$depth = -1;
$max_depth = 1// Setting to 1 returns top level terms only (in relation $parent)
                        // as all others will be acquired using taxonomy_get_children()
$term = array();  // Will hold the term id argument to be passed to the view
$terms1 = taxonomy_get_tree ($vid, $parent, $depth, $max_depth);
foreach (
$terms1 as $term1) {
  print
'<div class="term-top">' . $term1->name . '</div>';
 
$term[0] = $term1->tid;
  print
views_embed_view('productlist', 'default', $term[0]);
  if (
count ($terms2 = taxonomy_get_children ($term1->tid, $vid))) {
    foreach (
$terms2 as $term2) {
      print
'<div class="term-middle">' . $term2->name . '</div>';
     
$term[0] = $term2->tid;
      print
views_embed_view('productlist', 'default', $term[0]);
      if (
count ($terms3 = taxonomy_get_children ($term2->tid, $vid))) {
        foreach (
$terms3 as $term3) {
          print
'<div class="term-bottom">' . $term3->name . '</div>';
         
$term[0] = $term3->tid;
          print
views_embed_view('productlist', 'default', $term[0]);
        }
      }
    }
  }
}
?>

It's moments like these I really love Drupal.

Could you tell from my

harrisben's picture

Could you tell from my comments about the need to declare $term as an array that I had no idea about arrays? I'm a teensy bit more confident about them now :)

Hey Harris, I had to do

dalejung's picture

Hey Harris,

I had to do something similar. What I did was get the whole tree instead of using max_depth = 1. I did a quick transformation to create an actual nested structure instead of the flat list that taxonomy_get_tree returns.
So something like

term1
  children = array(
    term2,
    term3
      children = array( term 4)
    )
term 5
etc etc

That way I could just make a recursive call like:

function process( $terms ) {
  foreach($terms as $term) {
    // output current term, view, whatever
    if ($term->children) {
      process($term->children);   
    }
  }
}

Also, I wouldn't use print other than to print out debug info. It requires that you place all your logic in the same place that it is going to output. If you stored the output and ran it through a theme function, you could separate out the logic.

Anyways, sorry for the pseudo code, not on my dev lappy.

I understand conceptually

harrisben's picture

I understand conceptually what you're talking about... :) I need to read my php book about arrays a bit more before I'm comfortable approaching that.

Advice/Pointers needed

harrisben's picture

Howdy all,

As I predicted, the size of the page is becoming a problem now that there are more products on it and the research I've done to find a way to display content collapsed without actually loading it hasn't been fruitful (it's ongoing).

Does anyone know of some good tutorials on how to accomplish either aspect of this that might help me on my way?

Help, as always, is appreciated

Collapsed, unloaded content?

Senpai's picture

It sounds like what you're talking about is an empty div. What do you mean by collapsed, unloaded content? Please elaborate.
______________________________
Senpai  ~ Want a better WorkHabit? ~


Joel Farris | my 'certified to rock' score
Transparatech
http://transparatech.com
619.717.2805

Sorry, I'm probably confusing my terms

harrisben's picture

I mean that I don't want to actually load all of the content on page load. I only want to load it when a category is clicked, upon which it will expand to display everything contained therein.

To begin with I'd like to get just the top level terms to display and to expand and load their content when clicked.

A Minor but Important Update

harrisben's picture

While I'm still working on how to achieve the final parts of this I thought it would be good to point out something very important that I've run across.

When I completed putting the current price list up I found that both IE and FF (but not Chrome) were giving scripting errors. I honestly couldn't work out what it was until I looked at the source for the offending page and saw a whole lot of views 'stuff' being loaded via jquery.

Unbeknownst to me I'd left the 'Use AJAX' option on in my view from when I was attempting to solve this problem in a different (ie wrong) way and with the large number of views I am loading it was causing problems. Switching it off has fixed the problem thankfully and the page now loads a mite quicker.

More updates coming soon.

Very interesting, looking

Summit's picture

Very interesting, looking for argument handling and filtering on two seperate taxonomy terms.
Is your code in the argument handling area?

Greetings,
Martijn

No, my code is actually in a

harrisben's picture

No, my code is actually in a node (which is bad and I will eventually move it to template.php). My view is fairly basic using %1 as an argument so that when I submit the term for each loop it outputs any products under the term.

Sorry if my explanation isn't very good. If you look at the code above you should be able to figure out what it does as my php is basic so therefore my code is too :)