Error message

The spam filter installed on this site is currently unavailable. Per site policy, we are unable to accept new submissions until that problem is resolved. Please try resubmitting the form in a couple of minutes.

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'.


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'
  • 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; }

  switch ($options['sort']) {
    case "none":
      // sort counts in descending order

  // 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);
  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!


Thank's !

Add new comment