diff --git a/core/modules/views/config/schema/views.style.schema.yml b/core/modules/views/config/schema/views.style.schema.yml index 6e54683..ef1aed4 100644 --- a/core/modules/views/config/schema/views.style.schema.yml +++ b/core/modules/views/config/schema/views.style.schema.yml @@ -35,24 +35,18 @@ views.style.grid: alignment: type: string label: 'Alignment' - row_class: + row_class_custom: type: string label: 'Custom row classes' - default_row_class: + row_class_default: type: boolean label: 'Default views row classes' - row_class_special: - type: boolean - label: 'First, last and zebra striping row classes' - col_class: + col_class_custom: type: string label: 'Custom column classes' - default_col_class: + col_class_default: type: boolean label: 'Default views column classes' - col_class_special: - type: boolean - label: 'First, last and zebra striping column classes' views.style.table: type: views_style 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 91e438a..cb45df6 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 @@ -33,50 +33,37 @@ class Grid extends StylePluginBase { protected $usesRowPlugin = TRUE; /** - * Does the style plugin support custom css class for the rows. - * - * @var bool - */ - protected $usesRowClass = TRUE; - - /** - * Set default options + * {@inheritdoc} */ protected function defineOptions() { $options = parent::defineOptions(); $options['columns'] = array('default' => '4'); - $options['automatic_width'] = array('default' => TRUE, 'bool' => TRUE); + $options['automatic_width'] = array('default' => TRUE); $options['alignment'] = array('default' => 'horizontal'); - $options['col_class'] = array('default' => ''); - $options['default_col_class'] = array('default' => TRUE, 'bool' => TRUE); - $options['col_class_special'] = array('default' => TRUE, 'bool' => TRUE); + $options['col_class_custom'] = array('default' => ''); + $options['col_class_default'] = array('default' => TRUE); + $options['row_class_custom'] = array('default' => ''); + $options['row_class_default'] = array('default' => TRUE); return $options; } /** - * Build the options form. + * {@inheritdoc} */ 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, + '#min' => 1, ); $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.'), + '#description' => t('The width of each column will be calculated automatically based on the number of columns provided. If additional classes are entered or a theme injects 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', @@ -84,29 +71,37 @@ 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['col_class'] = array( - '#title' => t('Column class'), - '#description' => t('The class to provide on each column.'), + $form['col_class_default'] = array( + '#title' => t('Default column classes'), + '#description' => t('Add the default views 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['col_class_default'], + ); + $form['col_class_custom'] = array( + '#title' => t('Custom column class'), + '#description' => t('Additional classes to provide on each column. Separated by a space.'), '#type' => 'textfield', '#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['col_class_custom']['#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.'), + $form['row_class_default'] = array( + '#title' => t('Default row classes'), + '#description' => t('Adds the default views 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.'), '#type' => 'checkbox', - '#default_value' => $this->options['default_col_class'], + '#default_value' => $this->options['row_class_default'], ); - $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'], + $form['row_class_custom'] = array( + '#title' => t('Custom row class'), + '#description' => t('Additional classes to provide on each row. Separated by a space.'), + '#type' => 'textfield', + '#default_value' => $this->options['row_class_custom'], ); + if ($this->usesFields()) { + $form['row_class_custom']['#description'] .= ' ' . t('You may use field tokens from as per the "Replacement patterns" used in "Rewrite the output of this field" for all fields.'); + } } } diff --git a/core/modules/views/lib/Drupal/views/Tests/Plugin/StyleGridTest.php b/core/modules/views/lib/Drupal/views/Tests/Plugin/StyleGridTest.php new file mode 100644 index 0000000..284d35e --- /dev/null +++ b/core/modules/views/lib/Drupal/views/Tests/Plugin/StyleGridTest.php @@ -0,0 +1,96 @@ + 'Style: Grid', + 'description' => 'Tests the grid style plugin.', + 'group' => 'Views Plugins', + ); + } + + /** + * Tests the grid style. + */ + public function testGrid() { + $view = views_get_view('test_grid'); + foreach (array('horizontal', 'vertical') as $alignment) { + $this->assertGrid($view, $alignment, 5); + $this->assertGrid($view, $alignment, 4); + $this->assertGrid($view, $alignment, 3); + $this->assertGrid($view, $alignment, 2); + $this->assertGrid($view, $alignment, 1); + } + } + + /** + * Generates a grid and asserts that it is displaying correctly. + * + * @param \Drupal\views\ViewExecutable $view + * The executable to prepare. + * @param string $alignment + * The alignment of the grid to test. + * @param int $columns + * The number of columns in the grid to test. + */ + protected function assertGrid(ViewExecutable $view, $alignment, $columns) { + $view->setDisplay('default'); + $view->initStyle(); + $view->initHandlers(); + $view->initQuery(); + $view->style_plugin->options['alignment'] = $alignment; + $view->style_plugin->options['columns'] = $columns; + $this->executeView($view); + $output = $view->preview(); + $output = drupal_render($output); + if (!in_array($alignment, $this->alignmentsTested)) { + $this->assertTrue(strpos($output, "
") !== FALSE, ucfirst($alignment) . " grid markup displays correctly."); + $this->alignmentsTested[] = $alignment; + } + $width = '0'; + switch ($columns) { + case 5: $width = '20'; break; + case 4: $width = '25'; break; + case 3: $width = '33.3333'; break; + case 2: $width = '50'; break; + case 1: $width = '100'; break; + } + $clearfix = ''; + if ($alignment == 'vertical') { + $clearfix = ' clearfix'; + } + $this->assertTrue(strpos($output, "views-col col-$columns$clearfix\" style=\"width: $width") !== FALSE, ucfirst($alignment) . " $columns column grid: automatic width calculated correctly."); + // Test to make sure column count does not exceed style option. + $extraColumn = $columns + 1; + $this->assertFalse(strpos($output, "col-$extraColumn") !== FALSE, ucfirst($alignment) . " $columns column grid: no extraneous columns exist."); + } + +} diff --git a/core/modules/views/templates/views-view-grid.html.twig b/core/modules/views/templates/views-view-grid.html.twig index 3492bb9..b96b694 100644 --- a/core/modules/views/templates/views-view-grid.html.twig +++ b/core/modules/views/templates/views-view-grid.html.twig @@ -23,7 +23,7 @@ */ #} {% if title %} -

{{ title }}

+

{{ title }}

{% endif %} {% if options.alignment == 'horizontal' %} diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_grid.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_grid.yml new file mode 100644 index 0000000..c2a8915 --- /dev/null +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_grid.yml @@ -0,0 +1,71 @@ +base_table: views_test_data +core: '8' +description: '' +status: '1' +display: + default: + display_options: + defaults: + fields: '0' + pager: '0' + pager_options: '0' + sorts: '0' + fields: + age: + field: age + id: age + relationship: none + table: views_test_data + plugin_id: numeric + id: + field: id + id: id + relationship: none + table: views_test_data + plugin_id: numeric + name: + field: name + id: name + relationship: none + table: views_test_data + plugin_id: string + pager: + options: + offset: '0' + type: none + pager_options: { } + sorts: + id: + field: id + id: id + order: ASC + relationship: none + table: views_test_data + plugin_id: numeric + style: + type: grid + options: + grouping: { } + columns: '4' + automatic_width: '1' + alignment: horizontal + col_class_default: '1' + col_class_custom: '' + row_class_default: '1' + row_class_custom: '' + row: + type: fields + display_plugin: default + display_title: Master + id: default + position: '0' + page_1: + display_options: + path: test-grid + display_plugin: page + display_title: 'Page display' + id: page_1 + position: '1' +label: '' +id: test_grid +tag: '' diff --git a/core/modules/views/views.theme.inc b/core/modules/views/views.theme.inc index 1fe66c0..b14498a 100644 --- a/core/modules/views/views.theme.inc +++ b/core/modules/views/views.theme.inc @@ -761,9 +761,8 @@ function template_preprocess_views_view_grid(&$vars) { $col = 0; $row = 0; $items = array(); - $row_count = count($vars['rows']); - $remainders = $row_count % $options['columns']; - $num_rows = floor($row_count / $options['columns']); + $remainders = count($vars['rows']) % $options['columns']; + $num_rows = floor(count($vars['rows']) / $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. @@ -777,29 +776,15 @@ function template_preprocess_views_view_grid(&$vars) { // Create attributes for row. $row_attributes = array('class' => array()); // Add default views row classes. - if ($options['default_row_class']) { + if ($options['row_class_default']) { $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'])); + // Add custom row classes. + $row_class = array_filter(explode(' ', $options['row_class_custom'])); if (!empty($row_class)) { $row_attributes['class'] = array_merge($row_attributes['class'], $row_class); } @@ -814,32 +799,20 @@ function template_preprocess_views_view_grid(&$vars) { // Create attributes for columns. $col_attributes = array('class' => array()); // Add default views column classes. - if ($options['default_col_class']) { + if ($options['col_class_default']) { $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'])); + // Add custom column classes. + $col_class = array_filter(explode(' ', $options['col_class_custom'])); 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']) { + if ($options['automatic_width']) { $col_attributes['style'] = 'width: ' . (100 / $options['columns']) . '%;'; } // Add column attributes to variables array. @@ -852,7 +825,7 @@ function template_preprocess_views_view_grid(&$vars) { // Increase, decrease or reset the appropriate integers. if ($horizontal) { - if ($col == 0) { + if ($col == 0 && $col != ($options['columns'] - 1)) { $col++; } elseif ($col >= ($options['columns'] - 1)) { @@ -875,7 +848,6 @@ function template_preprocess_views_view_grid(&$vars) { $remainders--; } } - $row_count--; } // Save the grid items to the variables array. $vars['items'] = $items;