5 * Preprocessors and theme functions for the Views UI.
8 use Drupal\Component\Render\FormattableMarkup;
9 use Drupal\Core\Form\FormState;
10 use Drupal\Core\Render\Element;
11 use Drupal\Core\Render\Element\Checkboxes;
12 use Drupal\Core\Render\Element\Radios;
14 use Drupal\Core\Template\Attribute;
17 * Prepares variables for Views UI display tab setting templates.
19 * Default template: views-ui-display-tab-setting.html.twig.
21 * @param array $variables
22 * An associative array containing:
23 * - link: The setting's primary link.
24 * - settings_links: An array of links for this setting.
25 * - defaulted: A boolean indicating the setting is in its default state.
26 * - overridden: A boolean indicating the setting has been overridden from
28 * - description: The setting's description.
29 * - description_separator: A boolean indicating a separator colon should be
30 * appended to the setting's description.
32 function template_preprocess_views_ui_display_tab_setting(&$variables) {
33 // Put the primary link to the left side.
34 array_unshift($variables['settings_links'], $variables['link']);
36 if (!empty($variables['overridden'])) {
37 $variables['attributes']['title'][] = t('Overridden');
40 // Append a colon to the description, if requested.
41 if ($variables['description'] && $variables['description_separator']) {
42 $variables['description'] .= t(':');
47 * Prepares variables for Views UI view listing templates.
49 * Default template: views-ui-view-listing-table.html.twig.
51 * @param array $variables
52 * An associative array containing:
53 * - headers: An associative array containing the headers for the view
55 * - rows: An associative array containing the rows data for the view
58 function template_preprocess_views_ui_views_listing_table(&$variables) {
59 // Convert the attributes to valid attribute objects.
60 foreach ($variables['headers'] as $key => $header) {
61 $variables['headers'][$key]['attributes'] = new Attribute($header['#attributes']);
64 if (!empty($variables['rows'])) {
65 foreach ($variables['rows'] as $key => $row) {
66 $variables['rows'][$key]['attributes'] = new Attribute($row['#attributes']);
72 * Prepares variables for Views UI display tab bucket templates.
74 * Default template: views-ui-display-tab-bucket.html.twig.
76 * @param array $variables
77 * An associative array containing:
78 * - element: An associative array containing the properties of the element.
79 * Properties used: #name, #overridden, #children, #title, #actions.
81 function template_preprocess_views_ui_display_tab_bucket(&$variables) {
82 $element = $variables['element'];
84 if (!empty($element['#overridden'])) {
85 $variables['attributes']['title'][] = t('Overridden');
88 $variables['name'] = isset($element['#name']) ? $element['#name'] : NULL;
89 $variables['overridden'] = isset($element['#overridden']) ? $element['#overridden'] : NULL;
90 $variables['content'] = $element['#children'];
91 $variables['title'] = $element['#title'];
92 $variables['actions'] = !empty($element['#actions']) ? $element['#actions'] : [];
96 * Prepares variables for Views UI build group filter form templates.
98 * Default template: views-ui-build-group-filter-form.html.twig.
100 * @param array $variables
101 * An associative array containing:
102 * - form: A render element representing the form.
104 function template_preprocess_views_ui_build_group_filter_form(&$variables) {
105 $form = $variables['form'];
107 // Prepare table of options.
117 // Prepare default selectors.
118 $form_state = new FormState();
119 $form['default_group'] = Radios::processRadios($form['default_group'], $form_state, $form);
120 $form['default_group_multiple'] = Checkboxes::processCheckboxes($form['default_group_multiple'], $form_state, $form);
121 $form['default_group']['All']['#title'] = '';
124 ['data' => $form['default_group']['All']],
127 'data' => \Drupal::config('views.settings')->get('ui.exposed_filter_any_label') == 'old_any' ? t('<Any>') : t('- Any -'),
129 'class' => ['class' => 'any-default-radios-row'],
132 // Remove the 'All' default_group form element because it's added to the
134 unset($variables['form']['default_group']['All']);
136 foreach (Element::children($form['group_items']) as $group_id) {
137 $form['group_items'][$group_id]['value']['#title'] = '';
139 $form['default_group'][$group_id],
140 $form['default_group_multiple'][$group_id],
142 // Remove these fields from the form since they are moved into the table.
143 unset($variables['form']['default_group'][$group_id]);
144 unset($variables['form']['default_group_multiple'][$group_id]);
148 '#url' => Url::fromRoute('<none>', [], [
150 'id' => 'views-remove-link-' . $group_id,
153 'views-button-remove',
154 'views-groups-remove-link',
157 'alt' => t('Remove this item'),
158 'title' => t('Remove this item'),
161 '#title' => new FormattableMarkup('<span>@text</span>', ['@text' => t('Remove')]),
163 $remove = [$form['group_items'][$group_id]['remove'], $link];
165 'default' => ['data' => $default],
166 'weight' => ['data' => $form['group_items'][$group_id]['weight']],
167 'title' => ['data' => $form['group_items'][$group_id]['title']],
168 'operator' => ['data' => $form['group_items'][$group_id]['operator']],
169 'value' => ['data' => $form['group_items'][$group_id]['value']],
170 'remove' => ['data' => $remove],
172 $rows[] = ['data' => $data, 'id' => 'views-row-' . $group_id, 'class' => ['draggable']];
174 $variables['table'] = [
176 '#header' => $header,
179 'class' => ['views-filter-groups'],
180 'id' => 'views-filter-groups',
185 'relationship' => 'sibling',
191 // Hide fields used in table.
192 unset($variables['form']['group_items']);
196 * Prepares variables for Views UI rearrange filter form templates.
198 * Default template: views-ui-rearrange-filter-form.html.twig.
200 * @param array $variables
201 * An associative array containing:
202 * - form: A render element representing the form.
204 function template_preprocess_views_ui_rearrange_filter_form(&$variables) {
205 $form = &$variables['form'];
206 $rows = $ungroupable_rows = [];
207 // Enable grouping only if > 1 group.
208 $variables['grouping'] = count(array_keys($form['#group_options'])) > 1;
210 foreach ($form['#group_renders'] as $group_id => $contents) {
211 // Header row for the group.
212 if ($group_id !== 'ungroupable') {
213 // Set up tabledrag so that it changes the group dropdown when rows are
214 // dragged between groups.
216 'table_id' => 'views-rearrange-filters',
218 'relationship' => 'sibling',
219 'group' => 'views-group-select',
220 'subgroup' => 'views-group-select-' . $group_id,
222 drupal_attach_tabledrag($form['override'], $options);
224 // Title row, spanning all columns.
226 // Add a cell to the first row, containing the group operator.
228 'class' => ['group', 'group-operator', 'container-inline'],
229 'data' => $form['filter_groups']['groups'][$group_id],
230 'rowspan' => max([2, count($contents) + 1]),
234 'class' => ['group', 'group-title'],
236 '#prefix' => '<span>',
237 '#markup' => $form['#group_options'][$group_id],
238 '#suffix' => '</span>',
243 'class' => ['views-group-title'],
245 'id' => 'views-group-title-' . $group_id,
248 // Row which will only appear if the group has nothing in it.
250 $class = 'group-' . (count($contents) ? 'populated' : 'empty');
251 $instructions = '<span>' . t('No filters have been added.') . '</span> <span class="js-only">' . t('Drag to add filters.') . '</span>';
252 // When JavaScript is enabled, the button for removing the group (if it's
253 // present) should be hidden, since it will be replaced by a link on the
255 if (!empty($form['remove_groups'][$group_id]['#type']) && $form['remove_groups'][$group_id]['#type'] == 'submit') {
256 $form['remove_groups'][$group_id]['#attributes']['class'][] = 'js-hide';
261 ['#markup' => $instructions],
262 $form['remove_groups'][$group_id],
268 'group-' . $group_id . '-message',
272 'id' => 'views-group-' . $group_id,
276 foreach ($contents as $id) {
277 if (isset($form['filters'][$id]['name'])) {
279 $row[]['data'] = $form['filters'][$id]['name'];
280 $form['filters'][$id]['weight']['#attributes']['class'] = ['weight'];
281 $row[]['data'] = $form['filters'][$id]['weight'];
282 $form['filters'][$id]['group']['#attributes']['class'] = ['views-group-select views-group-select-' . $group_id];
283 $row[]['data'] = $form['filters'][$id]['group'];
284 $form['filters'][$id]['removed']['#attributes']['class'][] = 'js-hide';
288 '#url' => Url::fromRoute('<none>'),
289 '#title' => new FormattableMarkup('<span>@text</span>', ['@text' => t('Remove')]),
293 'id' => 'views-remove-link-' . $id,
296 'views-button-remove',
297 'views-groups-remove-link',
300 'alt' => t('Remove this item'),
301 'title' => t('Remove this item'),
306 $form['filters'][$id]['removed'],
312 'class' => ['draggable'],
313 'id' => 'views-row-' . $id,
316 if ($group_id !== 'ungroupable') {
320 $ungroupable_rows[] = $row;
326 if (!$variables['grouping']) {
327 $form['filter_groups']['groups'][0]['#title'] = t('Operator');
330 if (!empty($ungroupable_rows)) {
332 t('Ungroupable filters'),
335 'data' => t('Group'),
336 'class' => ['views-hide-label'],
339 'data' => t('Remove'),
340 'class' => ['views-hide-label'],
343 $variables['ungroupable_table'] = [
345 '#header' => $header,
346 '#rows' => $ungroupable_rows,
348 'id' => 'views-rearrange-filters-ungroupable',
349 'class' => ['arrange'],
354 'relationship' => 'sibling',
362 $rows[] = [['data' => t('No fields available.'), 'colspan' => '2']];
365 // Set up tabledrag so that the weights are changed when rows are dragged.
366 $variables['table'] = [
370 'id' => 'views-rearrange-filters',
371 'class' => ['arrange'],
376 'relationship' => 'sibling',
382 // When JavaScript is enabled, the button for adding a new group should be
383 // hidden, since it will be replaced by a link on the client side.
384 $form['actions']['add_group']['#attributes']['class'][] = 'js-hide';
389 * Prepares variables for style plugin table templates.
391 * Default template: views-ui-style-plugin-table.html.twig.
393 * @param array $variables
394 * An associative array containing:
395 * - form: A render element representing the form.
397 function template_preprocess_views_ui_style_plugin_table(&$variables) {
398 $form = $variables['form'];
406 'data' => t('Sortable'),
410 'data' => t('Default order'),
414 'data' => t('Default sort'),
418 'data' => t('Hide empty column'),
422 'data' => t('Responsive'),
427 foreach (Element::children($form['columns']) as $id) {
429 $row[]['data'] = $form['info'][$id]['name'];
430 $row[]['data'] = $form['columns'][$id];
431 $row[]['data'] = $form['info'][$id]['align'];
432 $row[]['data'] = $form['info'][$id]['separator'];
434 if (!empty($form['info'][$id]['sortable'])) {
436 'data' => $form['info'][$id]['sortable'],
440 'data' => $form['info'][$id]['default_sort_order'],
444 'data' => $form['default'][$id],
454 'data' => $form['info'][$id]['empty_column'],
458 'data' => $form['info'][$id]['responsive'],
464 // Add the special 'None' row.
465 $rows[] = [['data' => t('None'), 'colspan' => 6], ['align' => 'center', 'data' => $form['default'][-1]], ['colspan' => 2]];
467 // Unset elements from the form array that are used to build the table so that
468 // they are not rendered twice.
469 unset($form['default']);
470 unset($form['info']);
471 unset($form['columns']);
473 $variables['table'] = [
475 '#theme' => 'table__views_ui_style_plugin_table',
476 '#header' => $header,
479 $variables['form'] = $form;
483 * Prepares variables for views UI view preview section templates.
485 * Default template: views-ui-view-preview-section.html.twig.
487 * @param array $variables
488 * An associative array containing:
489 * - view: The view object.
490 * - section: The section name of a View (e.g. title, rows or pager).
492 function template_preprocess_views_ui_view_preview_section(&$variables) {
493 switch ($variables['section']) {
495 $variables['title'] = t('Title');
496 $links = views_ui_view_preview_section_display_category_links($variables['view'], 'title', $variables['title']);
499 $variables['title'] = t('Header');
500 $links = views_ui_view_preview_section_handler_links($variables['view'], $variables['section']);
503 $variables['title'] = t('No results behavior');
504 $links = views_ui_view_preview_section_handler_links($variables['view'], $variables['section']);
507 // @todo Sorts can be exposed too, so we may need a better title.
508 $variables['title'] = t('Exposed Filters');
509 $links = views_ui_view_preview_section_display_category_links($variables['view'], 'exposed_form_options', $variables['title']);
512 // @todo The title needs to depend on what is being viewed.
513 $variables['title'] = t('Content');
514 $links = views_ui_view_preview_section_rows_links($variables['view']);
517 $variables['title'] = t('Pager');
518 $links = views_ui_view_preview_section_display_category_links($variables['view'], 'pager_options', $variables['title']);
521 $variables['title'] = t('More');
522 $links = views_ui_view_preview_section_display_category_links($variables['view'], 'use_more', $variables['title']);
525 $variables['title'] = t('Footer');
526 $links = views_ui_view_preview_section_handler_links($variables['view'], $variables['section']);
528 case 'attachment_before':
529 // @todo: Add links to the attachment configuration page.
530 $variables['title'] = t('Attachment before');
532 case 'attachment_after':
533 // @todo: Add links to the attachment configuration page.
534 $variables['title'] = t('Attachment after');
540 '#theme' => 'links__contextual',
542 '#attributes' => ['class' => ['contextual-links']],
544 'library' => ['contextual/drupal.contextual-links'],
547 $variables['links'] = $build;