From bb653462e494746a144b8b3e59975212ddff843a Mon Sep 17 00:00:00 2001 From: Mark Carver Date: Fri, 28 Jun 2013 10:06:03 -0500 Subject: Issue #1903746 by Mark Carver, mgifford, tkoleary, DaneMacaulay: Replace the views grid table template with one using divs --- .../views/config/schema/views.style.schema.yml | 23 ++- core/modules/views/css/views.module.css | 10 + .../lib/Drupal/views/Plugin/views/style/Grid.php | 55 ++++-- .../views/templates/views-view-grid.html.twig | 53 ++++-- core/modules/views/views.theme.inc | 210 ++++++++++++--------- 5 files changed, 219 insertions(+), 132 deletions(-) diff --git a/core/modules/views/config/schema/views.style.schema.yml b/core/modules/views/config/schema/views.style.schema.yml index 15dae70..a845ec4 100644 --- a/core/modules/views/config/schema/views.style.schema.yml +++ b/core/modules/views/config/schema/views.style.schema.yml @@ -29,15 +29,30 @@ views.style.grid: columns: type: integer label: 'Number of columns' + automatic_width: + type: boolean + label: 'Automatic width' alignment: type: string label: 'Alignment' - fill_single_line: + row_class: + type: string + label: 'Custom row classes' + default_row_class: + type: boolean + label: 'Default views row classes' + row_class_special: + type: string + label: 'First, last and zebra striping row classes' + col_class: + type: string + label: 'Custom column classes' + default_col_class: type: boolean - label: 'Fill up single line' - summary: + label: 'Default views column classes' + col_class_special: type: string - label: 'Table summary' + label: 'First, last and zebra striping column classes' views.style.table: type: views_style diff --git a/core/modules/views/css/views.module.css b/core/modules/views/css/views.module.css index 7ca2f49..851a244 100644 --- a/core/modules/views/css/views.module.css +++ b/core/modules/views/css/views.module.css @@ -22,3 +22,13 @@ .view .progress-disabled { float: none; } + +/* grid style column align */ +.views-view-grid .views-col { + float: left; +} +.views-view-grid .views-row { + clear: both; + float: left; + width: 100%; +} diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/style/Grid.php b/core/modules/views/lib/Drupal/views/Plugin/views/style/Grid.php index 0631661..91e438a 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/style/Grid.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/style/Grid.php @@ -44,26 +44,39 @@ class Grid extends StylePluginBase { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['columns'] = array('default' => '4'); + $options['automatic_width'] = array('default' => TRUE, 'bool' => TRUE); $options['alignment'] = array('default' => 'horizontal'); - $options['fill_single_line'] = array('default' => TRUE, 'bool' => TRUE); - $options['summary'] = array('default' => ''); - + $options['col_class'] = array('default' => ''); + $options['default_col_class'] = array('default' => TRUE, 'bool' => TRUE); + $options['col_class_special'] = array('default' => TRUE, 'bool' => TRUE); return $options; } /** - * Render the given style. + * Build the options form. */ public function buildOptionsForm(&$form, &$form_state) { parent::buildOptionsForm($form, $form_state); + if (!empty($form['uses_fields'])) { + $form['uses_fields']['#weight'] = -10; + } + $form['default_row_class']['#description'] = t('Add the default row classes like views-row, row-1 and clearfix to the output. You can use this to quickly reduce the amount of markup the view provides by default, at the cost of making it more difficult to apply CSS.'); + $form['row_class_special']['#description'] = t('Add css classes to the first and last rows, as well as odd/even classes for striping.'); $form['columns'] = array( '#type' => 'number', '#title' => t('Number of columns'), '#default_value' => $this->options['columns'], '#required' => TRUE, '#min' => 0, + '#weight' => -9, + ); + $form['automatic_width'] = array( + '#type' => 'checkbox', + '#title' => t('Automatic width'), + '#description' => t('The width of each column will be calculated automatically based on the number of columns entered. If additional classes are entered or a theme injects additional classes based on a grid system, disabling this option may prove beneficial.'), + '#default_value' => $this->options['automatic_width'], + '#weight' => -8, ); $form['alignment'] = array( '#type' => 'radios', @@ -71,20 +84,28 @@ public function buildOptionsForm(&$form, &$form_state) { '#options' => array('horizontal' => t('Horizontal'), 'vertical' => t('Vertical')), '#default_value' => $this->options['alignment'], '#description' => t('Horizontal alignment will place items starting in the upper left and moving right. Vertical alignment will place items starting in the upper left and moving down.'), + '#weight' => -7, ); - - $form['fill_single_line'] = array( - '#type' => 'checkbox', - '#title' => t('Fill up single line'), - '#description' => t('If you disable this option, a grid with only one row will have the same number of table cells () as items. Disabling it can cause problems with your CSS.'), - '#default_value' => !empty($this->options['fill_single_line']), - ); - - $form['summary'] = array( + $form['col_class'] = array( + '#title' => t('Column class'), + '#description' => t('The class to provide on each column.'), '#type' => 'textfield', - '#title' => t('Table summary'), - '#description' => t('This value will be displayed as table-summary attribute in the html. Set this for better accessiblity of your site.'), - '#default_value' => $this->options['summary'], + '#default_value' => $this->options['col_class'], + ); + if ($this->usesFields()) { + $form['col_class']['#description'] .= ' ' . t('You may use field tokens from as per the "Replacement patterns" used in "Rewrite the output of this field" for all fields.'); + } + $form['default_col_class'] = array( + '#title' => t('Add views column classes'), + '#description' => t('Add the default column classes like views-col, col-1 and clearfix to the output. You can use this to quickly reduce the amount of markup the view provides by default, at the cost of making it more difficult to apply CSS.'), + '#type' => 'checkbox', + '#default_value' => $this->options['default_col_class'], + ); + $form['col_class_special'] = array( + '#title' => t('Add striping (odd/even), first/last column classes'), + '#description' => t('Add css classes to the first and last columns, as well as odd/even classes for striping.'), + '#type' => 'checkbox', + '#default_value' => $this->options['col_class_special'], ); } diff --git a/core/modules/views/templates/views-view-grid.html.twig b/core/modules/views/templates/views-view-grid.html.twig index 8b63792..3492bb9 100644 --- a/core/modules/views/templates/views-view-grid.html.twig +++ b/core/modules/views/templates/views-view-grid.html.twig @@ -4,32 +4,47 @@ * Default theme implementation for views to display rows in a grid. * * Available variables: - * - attributes: HTML attributes for the table element. + * - attributes: HTML attributes for the wrapping div element. * - title: The title of this group of rows. - * - rows: A list of rows. Each row contains a list of columns. - * - row_classes: HTML classes for each row including the row number and first - * or last. - * - column_classes: HTML classes for each column including the row number and - * first or last. + * - view: The view object. + * - rows: The rendered view results array. + * - options: The view plugin style options. + * - items: Contains a nested array of grid items. The structure of this array + * - depends on the value of options.alignment. + * - row_attributes: HTML attributes for each grid row. The structure of this + * array depends on the value of options.alignment. + * - col_attributes: HTML attributes for each grid column. The structure of this + * array depends on the value of options.alignment. * * @see template_preprocess_views_view_grid() * * @ingroup themeable + * @ingroup views_templates */ #} {% if title %} -

{{ title }}

+

{{ title }}

{% endif %} - - - {% for row_number, columns in rows %} - - {% for column_number, item in columns %} - - {{ item }} - - {% endfor %} - + +{% if options.alignment == 'horizontal' %} + {% for row_key, row in items %} + + {% for col_key, col in row %} + + {{ items[row_key][col_key] }} + {% endfor %} - - + + {% endfor %} +{% else %} + {% for col_key, column in items %} + + {% for row_key, row in column %} + + {{ items[col_key][row_key] }} + + {% endfor %} + + {% endfor %} +{% endif %} + diff --git a/core/modules/views/views.theme.inc b/core/modules/views/views.theme.inc index d52bce0..5494b1a 100644 --- a/core/modules/views/views.theme.inc +++ b/core/modules/views/views.theme.inc @@ -746,56 +746,125 @@ function template_preprocess_views_view_table(&$vars) { * - rows: An array of row items. Each row is an array of content. */ function template_preprocess_views_view_grid(&$vars) { - $view = $vars['view']; - $options = $view->style_plugin->options; - $handler = $view->style_plugin; - $default_row_class = isset($options['default_row_class']) ? $options['default_row_class'] : TRUE; - $row_class_special = isset($options['row_class_special']) ? $options['row_class_special'] : TRUE; + $options = $vars['options'] = $vars['view']->style_plugin->options; + $horizontal = ($options['alignment'] === 'horizontal'); - $columns = $options['columns']; - $vars['attributes']['class'][] = 'views-view-grid cols-' . $columns; + $vars['attributes'] = new Attribute(array( + 'class' => array( + 'views-view-grid', + $options['alignment'], + 'cols-' . $options['columns'], + 'clearfix', + ), + )); - $rows = array(); - $row_indexes = array(); + $col = 0; + $row = 0; + $items = array(); + $row_count = count($vars['rows']); + $remainders = $row_count % $options['columns']; + $num_rows = floor($row_count / $options['columns']); + // Iterate over the view rows array. + foreach ($vars['rows'] as $row_index => $item) { + // Add the current views data row to the rows array. + if ($horizontal) { + $items[$row][$col] = $item; + } + else { + $items[$col][$row] = $item; + } - if ($options['alignment'] == 'horizontal') { - $row = array(); - $col_count = 0; - $row_count = 0; - $count = 0; - foreach ($vars['rows'] as $row_index => $item) { - $count++; - $row[] = $item; - $row_indexes[$row_count][$col_count] = $row_index; - $col_count++; - if ($count % $columns == 0) { - $rows[] = $row; - $row = array(); - $col_count = 0; - $row_count++; - } - } - if ($row) { - // Fill up the last line only if it's configured, but this is default. - if (!empty($handler->options['fill_single_line']) && count($rows)) { - for ($i = 0; $i < ($columns - $col_count); $i++) { - $row[] = ''; - } - } - $rows[] = $row; - } - } - else { - $num_rows = floor(count($vars['rows']) / $columns); - // The remainders are the 'odd' columns that are slightly longer. - $remainders = count($vars['rows']) % $columns; - $row = 0; - $col = 0; - foreach ($vars['rows'] as $count => $item) { - $rows[$row][$col] = $item; - $row_indexes[$row][$col] = $count; + // Create attributes for row. + $row_attributes = array('class' => array()); + // Add default views row classes. + if ($options['default_row_class']) { + $row_attributes['class'][] = 'views-row'; + $row_attributes['class'][] = 'row-' . ($row + 1); + } + // Add special views row classes. + if ($options['row_class_special']) { + // First row. + if ($row == 0) { + $row_attributes['class'][] = 'first'; + } + // Last row. + if (($horizontal && $row == (!$remainders ? $num_rows - 1 : $num_rows)) || (!$horizontal && ((!$remainders && $row == $num_rows - 1) || ($remainders && $row == $num_rows)))) { + $row_attributes['class'][] = 'last'; + } + // Zebra striping. + $row_attributes['class'][] = (($row + 1) % 2) ? 'odd' : 'even'; + // Clearfix + if ($horizontal) { + $row_attributes['class'][] = 'clearfix'; + } + } + // Add custom row class. + $row_class = array_filter(explode(' ', $options['row_class'])); + if (!empty($row_class)) { + $row_attributes['class'] = array_merge($row_attributes['class'], $row_class); + } + // Add row attributes to variables array. + if ($horizontal) { + $vars['row_attributes'][$row] = new Attribute($row_attributes); + } + else { + $vars['row_attributes'][$col][$row] = new Attribute($row_attributes); + } + + // Create attributes for columns. + $col_attributes = array('class' => array()); + // Add default views column classes. + if ($options['default_col_class']) { + $col_attributes['class'][] = 'views-col'; + $col_attributes['class'][] = 'col-' . ($col + 1); + } + // Add special views row classes. + if ($options['col_class_special']) { + if ($col == 0) { + $col_attributes['class'][] = 'first'; + } + if ($col == $options['columns'] - 1 || ($row_count <= $num_rows && $col == $row_count)) { + $col_attributes['class'][] = 'last'; + } + // Zebra striping. + $col_attributes['class'][] = (($col + 1) % 2) ? 'odd' : 'even'; + // Clearfix + if (!$horizontal) { + $col_attributes['class'][] = 'clearfix'; + } + } + // Add custom column class. + $col_class = array_filter(explode(' ', $options['col_class'])); + if (!empty($col_class)) { + $col_attributes['class'] = array_merge($col_attributes['class'], $col_class); + } + // Add width to columns. + if ($options['columns'] > 1 && $options['automatic_width']) { + $col_attributes['style'] = 'width: ' . (100 / $options['columns']) . '%;'; + } + // Add column attributes to variables array. + if ($horizontal) { + $vars['col_attributes'][$row][$col] = new Attribute($col_attributes); + } + else { + $vars['col_attributes'][$col] = new Attribute($col_attributes); + } + + // Increase, decrease or reset the appropriate integers. + if ($horizontal) { + if ($col == 0) { + $col++; + } + elseif ($col >= ($options['columns'] - 1)) { + $col = 0; + $row++; + } + else { + $col++; + } + } + else { $row++; - if (!$remainders && $row == $num_rows) { $row = 0; $col++; @@ -806,53 +875,10 @@ function template_preprocess_views_view_grid(&$vars) { $remainders--; } } - for ($i = 0; $i < count($rows[0]); $i++) { - // This should be a string so this is ok. - if (!isset($rows[count($rows) - 1][$i])) { - $rows[count($rows) - 1][$i] = ''; - } - } - } - - // Apply the row classes. - foreach ($rows as $row_number => $row) { - $row_classes = array(); - if ($default_row_class) { - $row_classes['class'][] = 'row-' . ($row_number + 1); - } - if ($row_class_special) { - if ($row_number == 0) { - $row_classes['class'][] = 'row-first'; - } - if (count($rows) == ($row_number + 1)) { - $row_classes['class'][] = 'row-last'; - } - } - $row_classes = new Attribute($row_classes); - - foreach ($rows[$row_number] as $column_number => $item) { - $vars['column_classes'][$row_number][$column_number] = array(); - if ($default_row_class) { - $vars['column_classes'][$row_number][$column_number]['class'][] = 'col-' . ($column_number + 1); - } - if ($row_class_special) { - if ($column_number == 0) { - $vars['column_classes'][$row_number][$column_number]['class'][] = 'col-first'; - } - elseif (count($rows[$row_number]) == ($column_number + 1)) { - $vars['column_classes'][$row_number][$column_number]['class'][] = 'col-last'; - } - } - if (isset($row_indexes[$row_number][$column_number]) && $column_class = $view->style_plugin->getRowClass($row_indexes[$row_number][$column_number])) { - $vars['column_classes'][$row_number][$column_number]['class'][] = $column_class; - } - $vars['column_classes'][$row_number][$column_number] = new Attribute($vars['column_classes'][$row_number][$column_number]); - } - } - $vars['rows'] = $rows; - if (!empty($handler->options['summary'])) { - $vars['attributes']['summary'] = $handler->options['summary']; + $row_count--; } + // Save the grid items to the variables array. + $vars['items'] = $items; } /** -- 1.8.2