Index: includes/plugins.inc =================================================================== --- includes/plugins.inc (revision 2) +++ includes/plugins.inc (working copy) @@ -80,6 +80,7 @@ 'handler' => 'views_plugin_style_default', 'theme' => 'views_view_unformatted', 'uses row plugin' => TRUE, + 'uses options' => TRUE, 'type' => 'normal', ), 'list' => array( @@ -2421,8 +2422,28 @@ /** * Static member function to set default options. */ - function options(&$options) { } + function options(&$options) { + $options['grouping'] = ''; + } + function options_form(&$form, &$form_state) { + // Only fields-based rows can handle + + if (!empty($this->row_plugin->definition['uses fields'])) { + $options = array('' => t('')); + foreach ($this->display->handler->get_option('fields') as $field) { + $options[$field['table'] . '_' . $field['id']] = $field['label']; + } + $form['grouping'] = array( + '#type' => 'select', + '#title' => t('Grouping field'), + '#options' => $options, + '#default_value' => $this->options['grouping'], + '#description' => t('You may optionally specify a field by which to group the records. Leave blank to not group.'), + ); + } + } + /** * Called by the view builder to see if this style handler wants to * interfere with the sorts. If so it should build; if it returns @@ -2441,11 +2462,30 @@ vpr('views_plugin_style_default: Missing row plugin'); return; } - $rows = array(); - foreach ($this->view->result as $row) { - $rows[] = $this->row_plugin->render($row); + + // Group the rows according to the grouping field, if specified. + $sets = array(); + if ($this->options['grouping']) { + foreach ($this->view->result as $row) { + // @todo: Group on the rendered version of the field, not the raw. + $sets[$row->{$this->options['grouping']}][] = $row; + } } - return theme($this->theme_functions(), $this->view, $this->options, $rows); + else { + $sets[''] = $this->view->result; + } + + // Render each group separately and concatenate. Plugins may override this + // method if they wish some other way of handling grouping. + $output = ''; + foreach ($sets as $title => $records) { + $rows = array(); + foreach ($records as $label => $row) { + $rows[] = $this->row_plugin->render($row); + } + $output .= theme($this->theme_functions(), $this->view, $this->options, $rows, $title); + } + return $output; } function validate() { @@ -2465,19 +2505,28 @@ * decorations. */ class views_plugin_style_default extends views_plugin_style { + /** + * Set default options + */ + function options(&$options) { + parent::options($options); + } + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); // @todo -- separator option } } /** - * Style plugin to render each item in an ordered or unordered list + * Style plugin to render each item in an ordered or unordered list. */ class views_plugin_style_list extends views_plugin_style { /** * Set default options */ function options(&$options) { + parent::options($options); $options['type'] = 'ul'; } @@ -2485,6 +2534,7 @@ * Render the given style. */ function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); $form['type'] = array( '#type' => 'radios', '#title' => t('List type'), @@ -2502,6 +2552,7 @@ * Set default options */ function options(&$options) { + parent::options($options); $options['columns'] = 4; $options['alignment'] = 'horizontal'; } @@ -2510,6 +2561,7 @@ * Render the given style. */ function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); $form['columns'] = array( '#type' => 'textfield', '#title' => t('Number of columns'), @@ -2533,6 +2585,7 @@ * Set default options */ function options(&$options) { + parent::options($options); $options['columns'] = array(); $options['default'] = ''; $options['info'] = array(); @@ -2633,6 +2686,7 @@ * Render the given style. */ function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); $fields = $this->display->handler->get_option('fields'); if (empty($fields)) { $form['error_markup'] = array( @@ -2753,7 +2807,21 @@ * Render the table style. */ function render() { - return theme($this->theme_functions(), $this->view, $this->options, array()); + $sets = array(); + if ($this->options['grouping']) { + foreach ($this->view->result as $row) { + $sets[$row->{$this->options['grouping']}][] = $row; + } + } + else { + $sets[''] = $this->view->result; + } + + $output = ''; + foreach ($sets as $title => $records) { + $output .= theme($this->theme_functions(), $this->view, $this->options, $records, $title); + } + return $output; } } Index: theme/theme.inc =================================================================== --- theme/theme.inc (revision 2) +++ theme/theme.inc (working copy) @@ -187,7 +187,10 @@ */ function template_preprocess_views_view_table(&$vars) { $view = $vars['view']; - $result = $view->result; + $result = $vars['rows']; + // We're going to rebuild this variable below, but need to empty it first. + $vars['rows'] = array(); + $options = $view->style_handler->options; $handler = $view->style_handler; @@ -201,7 +204,7 @@ if ($query) { $query = '&' . $query; } - + foreach ($columns as $field => $column) { // render the header labels if ($field == $column) { Index: theme/views-view-list.tpl.php =================================================================== --- theme/views-view-list.tpl.php (revision 2) +++ theme/views-view-list.tpl.php (working copy) @@ -4,11 +4,15 @@ * @file views-view-list.tpl.php * Default simple view template to display a list of rows. * + * - $title : The title of this group of rows. May be empty. * - $options['type'] will either be ul or ol. * @ingroup views_templates */ ?>
+ +

+ <>
  • Index: theme/views-view-table.tpl.php =================================================================== --- theme/views-view-table.tpl.php (revision 2) +++ theme/views-view-table.tpl.php (working copy) @@ -4,6 +4,7 @@ * @file views-view-table.tpl.php * Template to display a view as a table. * + * - $title : The title of this group of rows. May be empty. * - $header: An array of header labels keyed by field id. * - $fields: An array of CSS IDs to use for each field id. * - $rows: An array of row items. Each row is an array of content @@ -12,6 +13,9 @@ */ ?> + + + $label): ?> Index: theme/views-view-unformatted.tpl.php =================================================================== --- theme/views-view-unformatted.tpl.php (revision 2) +++ theme/views-view-unformatted.tpl.php (working copy) @@ -7,6 +7,9 @@ * @ingroup views_templates */ ?> + +

    + \ No newline at end of file Index: views.module =================================================================== --- views.module (revision 2) +++ views.module (working copy) @@ -29,7 +29,7 @@ $arguments = array( 'display' => array('view' => NULL), - 'style' => array('view' => NULL, 'options' => NULL, 'rows' => NULL), + 'style' => array('view' => NULL, 'options' => NULL, 'rows' => NULL, 'title' => NULL), 'row' => array('view' => NULL, 'options' => NULL, 'row' => NULL), );