Drupal Views Group by Field with Counts
Note, since writing this article I learned about Views Arguments 'action to take if argument not present' summary list with counts... it is definitely easier than the approach I documented below. I'll leave what I have done below because I'm not sure the summary list option will handle all cases. Someday I'll update this post to include a tutorial on how to use the aformentioned approach, someday.
UPDATE: I have written a better blog post with a much cleaner (and simpler) solution to the problem described below.
The problem...
A solution...
Here's how it can be done with theme_preprocess_views_view in my theme's template.php file and by utilizing views-view.tpl.php for my view 'events_location_count'.
template.php
function tf_preprocess_views_view (&$vars) { switch ($vars['view']->name) { case "events_location_count": $args = array( 'variable_name' => 'events_location_counts', 'views_grouping_field' => 'node_node_data_field_event_location_nid', 'views_grouping_field_title' => 'node_node_data_field_event_location_title' ); tf_views_grouping_field_count_template_variable($vars,$args); break; } }
- This function can be called by template_preprocess_views_view.
- It works with views that have a 'grouping field' specified under 'basic settings -> style -> unformatted -> settings'.
- The function iterates through the view's results and stores individual counts for how many results show up in each 'grouping_field'.
- The function needs to know the 'grouping field' (sql column or alias) and the variable name you would like to show up in your views template file.
function tf_views_grouping_field_count_template_variable (&$vars,$options = array()) { $variable_name = $options['variable_name']; $views_grouping_field = $options['views_grouping_field']; $views_grouping_field_title = $options['views_grouping_field_title']; if (!$variable_name || !$views_grouping_field) { return; } // generate counts for the views grouping field $vars[$variable_name] = array(); foreach ($vars['view']->result as $result) { $index = $result->$views_grouping_field; if (!$vars[$variable_name][$index]) { $vars[$variable_name][$index] = 0; } $vars[$variable_name][$index]++; } switch ($options['sort']) { case "none": break; default: // sort counts in descending order arsort($vars[$variable_name]); break; } // build an array of each group count $views_grouping_field_links = array(); foreach ($vars[$variable_name] as $index => $count) { foreach ($vars['view']->result as $result) { if ($index == $result->$views_grouping_field) { $title = $result->$views_grouping_field; if ($views_grouping_field_title) { $title = $result->$views_grouping_field_title; } $views_grouping_field_links[] = array('title' => $title,'count' => $count,'index' => $index); break; } } } if (!empty($views_grouping_field_links)) { $vars['views_grouping_field_links'] = $views_grouping_field_links; } }
views-view.tpl.php - For example, my file needed to be named: views-view--events-location-count.tpl.php
And finally we need to theme our view, replace 'print $rows;' with code similar to the following: (This is where you can customize your output of course, the following is just the basics.)
if (!empty($views_grouping_field_links)) { $item_list = array(); foreach ($views_grouping_field_links as $link) $item_list[] = $link['title'] . " (" . $link['count'] . ")"; print theme_item_list($item_list); }
For the love of the Drupal Gods, if there is an easier way to do this please let me know. I searched and searched and couldn't find anything, so had to hack up a solution. Hope this helps somebody out there!
Comments
Alex (not verified)
Thu, 12/15/2011 - 08:12
Permalink
Thank's !
Thank's !