Error message

Deprecated function: implode(): Passing glue string after array is deprecated. Swap the parameters in drupal_get_feeds() (line 394 of /home1/tylerfra/public_html/includes/common.inc).

Drupal Views Group by Field with Counts

Category: 

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

Thank's !