Example: How to provide a view which contains taxonomy headers
One thing that is really handy is to be able to format a list like this:
- TERM
- node title ...
- node title ...
- node title ...
- TERM
- node title ...
- node title ...
- node title ...
A great example would be recipes:
- Chinese
- Dou Miao -- Dou Miao is a...
- Beef and Broccoli -- Descriptions are good
- Szechuan Pork -- Dig your fork into...
- Italian
- Lasagna -- Noodles and sauce
- Bolognese -- Meat meat and sauce
- Linguine alle Vongole -- Clams make this dish...
And so on...
Views can sort things this way, but it has no facility to add headers. Why? Well, we had to stop somewhere. The good news is, this is actually not too difficult to accomplish! We set up our theme as a List View, given the fields we want to put in. We could do this as a table view as well, but we'll have to adjust our theme slightly. That is left as an exercise to the reader.
1st create a view and specify it as a Page view and view type is "List View." The name of your view is referred to as VIEWNAME in the code below.
In order to designate what we want to group by, we'll give it a special label so that we can identify it in code. I'll call this XYZZY, which is actually literal (unlike the _VIEWNAME that I always use). What this means is that in the 'label' entry of the field, I put 'XYZZY'. The theme, here, will take that out of the list and keep it as the header. If you want to call the field something else, make sure to change "XYZZY" in the template.php below to the field name you want.
Be sure to put the field you want as a header both in your FIELDs section and your SORT section; otherwise it'll be a jumble!
template.php
Add this code (without the <?php ?> tags) to your template.php file.
<?php
function phptemplate_views_view_list_VIEWNAME($view, $nodes, $type) {
$fields = _views_get_fields();
$taken = array();
// Set up the fields in nicely named chunks.
foreach ($view->field as $id => $field) {
$field_name = $field['field'];
if (isset($taken[$field_name])) {
$field_name = $field['queryname'];
}
$taken[$field_name] = true;
$field_names[$id] = $field_name;
}
// Set up some variables that won't change.
$base_vars = array(
'view' => $view,
'view_type' => $type,
);
foreach ($nodes as $i => $node) {
$vars = $base_vars;
$vars['node'] = $node;
$vars['count'] = $i;
$vars['stripe'] = $i % 2 ? 'even' : 'odd';
foreach ($view->field as $id => $field) {
$name = $field_names[$id];
$vars[$name] = views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view);
if (isset($field['label'])) {
if ($field['label'] == 'XYZZY') {
if ($header != $vars[$name]) {
$new_header = $vars[$name];
}
}
else {
$vars[$name . '_label'] = $field['label'];
}
}
if ($new_header) {
if ($items) {
$main_items[] = theme('item_list', $items, $header);
}
// reset values for the next one.
$items = array();
$header = $new_header;
$new_header = '';
}
}
$items[] = _phptemplate_callback('views-list-VIEWNAME', $vars);
}
if ($items) {
$main_items[] = theme('item_list', $items, $header);
}
if ($items) {
return theme('item_list', $main_items);
}
}
?>Template (tpl.php) file
Create file called "views-list-VIEWNAME.tpl.php" (this can be created by theme wizard or you can just make your own) in your theme directory. This will control what each item listed in your view looks like.
<?php
/**
* views template to output one 'row' of a view.
* This code was generated by the views theming wizard
* View: VIEWNAME
*
* Variables available:
* $view -- the entire view object. Important parts of this object are
* compliance_wizard_monthly, .
* $view_type -- The type of the view. Probably 'page' or 'block' but could
* also be 'embed' or other string passed in from a custom view creator.
* $node -- the raw data. This is not a real node object, but will contain
* the nid as well as other support fields that might be necessary.
* $count -- the current row in the view (not TOTAL but for this page) starting
* from 0.
* $stripe -- 'odd' or 'even', alternating. * $description -- This will display the description associated with a taxonomy term.
* $description_label -- The assigned label for $description
* $title -- Display the title of the node.
* $title_label -- The assigned label for $title
* $body -- Display the Main Content.
* $body_label -- The assigned label for $body
* $name -- This will display all taxonomy terms associated with the node that are members of <em>Compliance</em>. Note that this causes one extra query per row displayed, and might have a minor performance impact.
* $name_label -- The assigned label for $name
*
* This function goes in your views-list-compliance_wizard_monthly.tpl.php file
*/
// This optionally adds a new stylesheet that you can get from the wizard output.
// This line, nor the CSS file are necessary if you just want to do styling in your
// theme's styles.css file.
drupal_add_css(path_to_theme() .'/views-list-VIEWNAME.css');
?>
<div class="view-field view-data-name">
<?php print $name?>
</div>
<div class="view-label view-field-title">
<?php print $title_label ?>
</div>
<div class="view-field view-data-title">
<?php print $title?>
</div>Stylesheet (optional)
Add the stylesheet "views-list-VIEWNAME.css" in your theme directory. (You get this file from the theme wizard as well.) Note that you don't need to include this if you just want to add the CSS styling directly in your theme's styles.css file.
/* *
* views template to output the stylesheet to customize a view.
* This code was generated by the views theming wizard
* View: VIEWNAME
*
* The class selectors are filled with a single comment line.
* You should complete each selector according to your liking.
*/
.view-label {
/* insert your css code for this element here */
}
.view-field {
/* insert your css code for this element here */
}
.view-field-name {
/* insert your css code for this element here */
}
.view-data-name {
/* insert your css code for this element here */
}
.view-field-title {
/* insert your css code for this element here */
}
.view-data-title {
/* insert your css code for this element here */
}Then if you go to the URL you specified in your Views module for this View, you should see the list as categorized by the field "XYZZY".

I tried this, but all I get
This didn't really work for me, but while trying to use it, I figured out my solution was actually quite simple. I first of all added "taxonomy: term" as a field (first field), then in my template I added an if statement:
<?php if ($count < 1) {?><div class="view-field view-data-name">
<?php print '<h2 id="view-title">'.$name.'</h2>';?>
</div>
<?php }?>
So the taxonomy term only gets printed once....problem solved!
Thanks Zahor
Hi,
Thanks for submitting your fix for this.
It's just saved me a lot of heartache!
John
Spoke too soon, this only outputs the category title for the first category.
...yea it was only supposed
...yea it was only supposed to display the first one (only using it with 1 term). But I think you can probably use some more logic to check to see if the same term is being displayed. I haven't thought about it completely, but I'd probably look at something like creating an array which stores the term name and each time a row is rendered, check to see if myarray[count] == myarray[count-1] - or something to that effect. Have not tried it, so I have no idea if that would work.
My solution
Hello,
I just used the Simple List as Theme Type. In my template I introduced a $prev_name var like this:
<?php
global $prev_name;
?>
<?php if ($name != $prev_name) : ?>
<div class="link-term">
<?php print $name; $prev_name = $name; ?>
</div>
<?php endif; ?>
<div class="<?php print $stripe; ?>">
<?php print $field_afbeelding_fid; ?>
<?php print $field_url_url; ?>
</div>
Quick and dirty but it works.
With best regards,
Fred Klopper