Last updated August 25, 2011. Created by merlinofchaos on December 29, 2005.
Edited by gagarine, linclark, el_reverend, add1sun. Log in to edit this page.
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".
Comments
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
To get above example the
To get above example the following tpl.php file is necessary. It is in the remarks text but anyway:
<?php if ($count < 0) {?>
<div class="view-field view-data-name">
<?php print '<h2 id="view-title">'.$name.'</h2>';?>
</div>
<?php }?>
<div class="view-label view-field-title">
<?php print $title_label ?>
</div>
<div class="view-field view-data-title">
<?php print $title?>
</div>
<div class="view-field view-data-title">
<?php print $body?>
</div>
Is this the same procedure for Drupal 6?
I would like to get this going but haven't found any documention for Views 2.x. In fact I've needed this more than once and would like to make a general, reusable, 'View' out of it but again, I can only see documentation on how to include your modules data into Views 2.x, not how to simply create a new 'view type' (?).
DOH! This is already part of Views 2. Most views styles give you a "Group by" option which does this for you (one level deep but, not bad).
Alexander Whillas
Taylor Square Designs
Berlin, Germany
Umm...
Could you explain where to find the mentioned "Group By" in Views2, i.e. a little howto ???
Taking this to a different
Taking this to a different level, is there a way to put one item under multiple categories?
I used this and it works great as is but it gives me multiple headings if the item has multiple categories instead of listing the item under a new heading for the second, third, etc. category.
Example:
Colors
-red
-blue
-green
Primary Colors
-red
-blue
Secondary Colors
-green
Currently, items red and blue come up with two headers like this:
Colors
Primary Colors
red
blue
thanks for any input
multiple categories
I'm having this issue too. Some of my nodes have 4 or 5 taxonomy terms from my multiselect vocabulary (of around 15 terms) and I'm getting many, many different combinations of category headings (like at the bottom of your example).
Does anyone have a solution?
Thanks for any suggestions.
No one has any ideas on this?
No one has any ideas on this?
D6?
This is relatively easy in D6 via table views, but if you are not using tables, is there a way w/out the override code, above (admittedly, it's not hard, but for end-users, it would be nicer to have it exposed in the UI).
Well, for *my* end-users !
Thanks,
I am struggling with
I am struggling with something similar. I have a list of retailers that carry multiple products, but not all products for each venue. Some of theses retailers also sell the product online. In addition these retailers are located on various countries.
So I created a content type to hold the Retailer Info, and two taxonomy vocabularies. One for the country, the other for the product line the retailer carries. So each retailer can have multiple product lines and reside in more than one country and at least one url.
What I wanted to do is to group the retailer information by country and then group the by product line. Kinda along the lines of this:
USA
- Shampoo
- Walmart
- Target
- CVS
- Conditioner
- Walmart
- CVS
CANADA
- Shampoo
- Walmart
- Superstore
- Conditioner
- Superstore
GERMANY
- Shampoo
- Walmart
- Aldi
ONLINE
- Shampoo
- Amazon
- CVS
and so on. But I cannot nest the two taxonomy vocabularies. I am still new to views themeing (other than CSS) and it's not fully clear on how to rewrite the row output of any of the theming templates provided by the Views module.
My question now is? Is there a better way of creating this type of information? Can Views be used to cluster information this way or should I go another route? Any advice is appreciated.