views_ui.module
Same filename in other branches
Provide structure for the administrative interface to Views.
File
-
core/
modules/ views_ui/ views_ui.module
View source
<?php
/**
* @file
* Provide structure for the administrative interface to Views.
*/
use Drupal\block\BlockInterface;
use Drupal\Component\Utility\Unicode;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\views\Entity\View;
use Drupal\views\ViewExecutable;
use Drupal\views\Analyzer;
/**
* Implements hook_help().
*/
function views_ui_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.views_ui':
$output = '';
$output .= '<h2>' . t('About') . '</h2>';
$output .= '<p>' . t('The Views UI module provides an interface for managing views for the <a href=":views">Views module</a>. For more information, see the <a href=":handbook">online documentation for the Views UI module</a>.', [
':views' => Url::fromRoute('help.page', [
'name' => 'views',
])->toString(),
':handbook' => 'https://www.drupal.org/documentation/modules/views_ui',
]) . '</p>';
$output .= '<h2>' . t('Uses') . '</h2>';
$output .= '<dl>';
$output .= '<dt>' . t('Creating and managing views') . '</dt>';
$output .= '<dd>' . t('Views can be created from the <a href=":list">Views list page</a> by using the "Add view" action. Existing views can be managed from the <a href=":list">Views list page</a> by locating the view in the "Enabled" or "Disabled" list and selecting the desired operation action, for example "Edit".', [
':list' => Url::fromRoute('entity.view.collection', [
'name' => 'views_ui',
])->toString(),
]) . '</dd>';
$output .= '<dt>' . t('Enabling and disabling views') . '<dt>';
$output .= '<dd>' . t('Views can be enabled or disabled from the <a href=":list">Views list page</a>. To enable a view, find the view within the "Disabled" list and select the "Enable" operation. To disable a view find the view within the "Enabled" list and select the "Disable" operation.', [
':list' => Url::fromRoute('entity.view.collection', [
'name' => 'views_ui',
])->toString(),
]) . '</dd>';
$output .= '<dt>' . t('Exporting and importing views') . '</dt>';
$output .= '<dd>' . t('Views can be exported and imported as configuration files by using the <a href=":config">Configuration Manager module</a>.', [
':config' => \Drupal::moduleHandler()->moduleExists('config') ? Url::fromRoute('help.page', [
'name' => 'config',
])->toString() : '#',
]) . '</dd>';
$output .= '</dl>';
return $output;
}
}
/**
* Implements hook_entity_type_build().
*/
function views_ui_entity_type_build(array &$entity_types) {
/** @var \Drupal\Core\Entity\EntityTypeInterface[] $entity_types */
$entity_types['view']->setFormClass('edit', 'Drupal\\views_ui\\ViewEditForm')
->setFormClass('add', 'Drupal\\views_ui\\ViewAddForm')
->setFormClass('preview', 'Drupal\\views_ui\\ViewPreviewForm')
->setFormClass('duplicate', 'Drupal\\views_ui\\ViewDuplicateForm')
->setFormClass('delete', 'Drupal\\Core\\Entity\\EntityDeleteForm')
->setFormClass('break_lock', 'Drupal\\views_ui\\Form\\BreakLockForm')
->setListBuilderClass('Drupal\\views_ui\\ViewListBuilder')
->setLinkTemplate('edit-form', '/admin/structure/views/view/{view}')
->setLinkTemplate('edit-display-form', '/admin/structure/views/view/{view}/edit/{display_id}')
->setLinkTemplate('preview-form', '/admin/structure/views/view/{view}/preview/{display_id}')
->setLinkTemplate('duplicate-form', '/admin/structure/views/view/{view}/duplicate')
->setLinkTemplate('delete-form', '/admin/structure/views/view/{view}/delete')
->setLinkTemplate('enable', '/admin/structure/views/view/{view}/enable')
->setLinkTemplate('disable', '/admin/structure/views/view/{view}/disable')
->setLinkTemplate('break-lock-form', '/admin/structure/views/view/{view}/break-lock')
->setLinkTemplate('collection', '/admin/structure/views');
}
/**
* Implements hook_theme().
*/
function views_ui_theme() {
return [
// Edit a view
'views_ui_display_tab_setting' => [
'variables' => [
'description' => '',
'link' => '',
'settings_links' => [],
'overridden' => FALSE,
'defaulted' => FALSE,
'description_separator' => TRUE,
'class' => [],
],
'file' => 'views_ui.theme.inc',
],
'views_ui_display_tab_bucket' => [
'render element' => 'element',
'file' => 'views_ui.theme.inc',
],
'views_ui_rearrange_filter_form' => [
'render element' => 'form',
'file' => 'views_ui.theme.inc',
],
'views_ui_expose_filter_form' => [
'render element' => 'form',
'file' => 'views_ui.theme.inc',
],
// Legacy theme hook for displaying views info.
'views_ui_view_info' => [
'variables' => [
'view' => NULL,
'displays' => NULL,
],
'file' => 'views_ui.theme.inc',
],
// List views.
'views_ui_views_listing_table' => [
'variables' => [
'headers' => NULL,
'rows' => NULL,
'attributes' => [],
],
'file' => 'views_ui.theme.inc',
],
'views_ui_view_displays_list' => [
'variables' => [
'displays' => [],
],
],
// Group of filters.
'views_ui_build_group_filter_form' => [
'render element' => 'form',
'file' => 'views_ui.theme.inc',
],
// On behalf of a plugin
'views_ui_style_plugin_table' => [
'render element' => 'form',
'file' => 'views_ui.theme.inc',
],
// When previewing a view.
'views_ui_view_preview_section' => [
'variables' => [
'view' => NULL,
'section' => NULL,
'content' => NULL,
'links' => '',
],
'file' => 'views_ui.theme.inc',
],
// Generic container wrapper, to use instead of theme_container when an id
// is not desired.
'views_ui_container' => [
'variables' => [
'children' => NULL,
'attributes' => [],
],
'file' => 'views_ui.theme.inc',
],
];
}
/**
* Implements hook_preprocess_HOOK() for views templates.
*/
function views_ui_preprocess_views_view(&$variables) {
$view = $variables['view'];
// Render title for the admin preview.
if (!empty($view->live_preview)) {
$variables['title'] = [
'#markup' => $view->getTitle(),
'#allowed_tags' => Xss::getHtmlTagList(),
];
}
if (!empty($view->live_preview) && \Drupal::moduleHandler()->moduleExists('contextual')) {
$view->setShowAdminLinks(FALSE);
foreach ([
'title',
'header',
'exposed',
'rows',
'pager',
'more',
'footer',
'empty',
'attachment_after',
'attachment_before',
] as $section) {
if (!empty($variables[$section])) {
$variables[$section] = [
'#theme' => 'views_ui_view_preview_section',
'#view' => $view,
'#section' => $section,
'#content' => $variables[$section],
'#theme_wrappers' => [
'views_ui_container',
],
'#attributes' => [
'class' => [
'contextual-region',
],
],
];
}
}
}
}
/**
* Implements hook_theme_suggestions_HOOK().
*/
function views_ui_theme_suggestions_views_ui_view_preview_section(array $variables) {
return [
'views_ui_view_preview_section__' . $variables['section'],
];
}
/**
* Returns contextual links for each handler of a certain section.
*
* @todo Bring in relationships.
* @todo Refactor this function to use much stuff of
* views_ui_edit_form_get_bucket.
*
* @param $title
* Add a bolded title of this section.
*/
function views_ui_view_preview_section_handler_links(ViewExecutable $view, $type, $title = FALSE) {
$display = $view->display_handler->display;
$handlers = $view->display_handler
->getHandlers($type);
$links = [];
$types = ViewExecutable::getHandlerTypes();
if ($title) {
$links[$type . '-title'] = [
'title' => $types[$type]['title'],
];
}
foreach ($handlers as $id => $handler) {
$field_name = $handler->adminLabel(TRUE);
$links[$type . '-edit-' . $id] = [
'title' => t('Edit @section', [
'@section' => $field_name,
]),
'url' => Url::fromRoute('views_ui.form_handler', [
'js' => 'nojs',
'view' => $view->storage
->id(),
'display_id' => $display['id'],
'type' => $type,
'id' => $id,
]),
'attributes' => [
'class' => [
'views-ajax-link',
],
],
];
}
$links[$type . '-add'] = [
'title' => t('Add new'),
'url' => Url::fromRoute('views_ui.form_add_handler', [
'js' => 'nojs',
'view' => $view->storage
->id(),
'display_id' => $display['id'],
'type' => $type,
]),
'attributes' => [
'class' => [
'views-ajax-link',
],
],
];
return $links;
}
/**
* Returns a link to editing a certain display setting.
*/
function views_ui_view_preview_section_display_category_links(ViewExecutable $view, $type, $title) {
$display = $view->display_handler->display;
$links = [
$type . '-edit' => [
'title' => t('Edit @section', [
'@section' => $title,
]),
'url' => Url::fromRoute('views_ui.form_display', [
'js' => 'nojs',
'view' => $view->storage
->id(),
'display_id' => $display['id'],
'type' => $type,
]),
'attributes' => [
'class' => [
'views-ajax-link',
],
],
],
];
return $links;
}
/**
* Returns all contextual links for the main content part of the view.
*/
function views_ui_view_preview_section_rows_links(ViewExecutable $view) {
$links = [];
$links = array_merge($links, views_ui_view_preview_section_handler_links($view, 'filter', TRUE));
$links = array_merge($links, views_ui_view_preview_section_handler_links($view, 'field', TRUE));
$links = array_merge($links, views_ui_view_preview_section_handler_links($view, 'sort', TRUE));
$links = array_merge($links, views_ui_view_preview_section_handler_links($view, 'argument', TRUE));
$links = array_merge($links, views_ui_view_preview_section_handler_links($view, 'relationship', TRUE));
return $links;
}
/**
* Implements hook_views_plugins_display_alter().
*/
function views_ui_views_plugins_display_alter(&$plugins) {
// Attach contextual links to each display plugin. The links will point to
// paths underneath "admin/structure/views/view/{$view->id()}" (i.e., paths
// for editing and performing other contextual actions on the view).
foreach ($plugins as &$display) {
$display['contextual links']['entity.view.edit_form'] = [
'route_name' => 'entity.view.edit_form',
'route_parameters_names' => [
'view' => 'id',
],
];
}
}
/**
* Implements hook_contextual_links_view_alter().
*/
function views_ui_contextual_links_view_alter(&$element, $items) {
// Remove contextual links from being rendered, when so desired, such as
// within a View preview.
if (views_ui_contextual_links_suppress()) {
$element['#links'] = [];
}
elseif (!empty($element['#links']['entityviewedit-form'])) {
$display_id = $items['entity.view.edit_form']['metadata']['display_id'];
$route_parameters = $element['#links']['entityviewedit-form']['url']->getRouteParameters() + [
'display_id' => $display_id,
];
$element['#links']['entityviewedit-form']['url'] = Url::fromRoute('entity.view.edit_display_form', $route_parameters);
}
}
/**
* Sets a static variable for controlling whether contextual links are rendered.
*
* @see views_ui_contextual_links_view_alter()
*/
function views_ui_contextual_links_suppress($set = NULL) {
$suppress =& drupal_static(__FUNCTION__);
if (isset($set)) {
$suppress = $set;
}
return $suppress;
}
/**
* Increments the views_ui_contextual_links_suppress() static variable.
*
* When this function is added to the #pre_render of an element, and
* 'views_ui_contextual_links_suppress_pop' is added to the #post_render of the
* same element, then all contextual links within the element and its
* descendants are suppressed from being rendered. This is used, for example,
* during a View preview, when it is not desired for nodes in the Views result
* to have contextual links.
*
* @see views_ui_contextual_links_suppress_pop()
*/
function views_ui_contextual_links_suppress_push() {
views_ui_contextual_links_suppress((int) views_ui_contextual_links_suppress() + 1);
}
/**
* Decrements the views_ui_contextual_links_suppress() static variable.
*
* @see views_ui_contextual_links_suppress_push()
*/
function views_ui_contextual_links_suppress_pop() {
views_ui_contextual_links_suppress((int) views_ui_contextual_links_suppress() - 1);
}
/**
* Implements hook_views_analyze().
*
* This is the basic views analysis that checks for very minimal problems.
* There are other analysis tools in core specific sections, such as
* node.views.inc as well.
*/
function views_ui_views_analyze(ViewExecutable $view) {
$ret = [];
// Check for something other than the default display:
if (count($view->displayHandlers) < 2) {
$ret[] = Analyzer::formatMessage(t('This view has only a default display and therefore will not be placed anywhere on your site; perhaps you want to add a page or a block display.'), 'warning');
}
// If a display has a path, check that it does not match an existing path
// alias. This results in the path alias not working.
foreach ($view->displayHandlers as $display) {
if (empty($display)) {
continue;
}
if ($display->hasPath() && ($path = $display->getOption('path'))) {
$normal_path = \Drupal::service('path_alias.manager')->getPathByAlias($path);
if ($path != $normal_path) {
$ret[] = Analyzer::formatMessage(t('You have configured display %display with a path which is an path alias as well. This might lead to unwanted effects so better use an internal path.', [
'%display' => $display->display['display_title'],
]), 'warning');
}
}
}
return $ret;
}
/**
* Truncate strings to a set length and provide a '...' if they truncated.
*
* This is often used in the UI to ensure long strings fit.
*
* @deprecated in drupal:10.3.0 and is removed from drupal:12.0.0.
* Use \Drupal\Component\Utility\Unicode::truncate().
*
* @see https://www.drupal.org/node/3408283
*/
function views_ui_truncate($string, $length) {
@trigger_error('views_ui_truncate() is deprecated in drupal:10.3.0 and is removed from drupal:12.0.0. Use \\Drupal\\Component\\Utility\\Unicode::truncate(). See https://www.drupal.org/node/3408283', E_USER_DEPRECATED);
return Unicode::truncate($string, $length, FALSE, TRUE);
}
/**
* Implements hook_entity_operation().
*/
function views_ui_entity_operation(EntityInterface $entity) : array {
$operations = [];
if ($entity instanceof BlockInterface) {
$plugin = $entity->getPlugin();
if ($plugin->getBaseId() === 'views_block') {
$view_id_parts = explode('-', $plugin->getDerivativeId());
$view_id = $view_id_parts[0] ?? '';
$display_id = $view_id_parts[1] ?? '';
$view = View::load($view_id);
if ($view && $view->access('edit')) {
$operations['view-edit'] = [
'title' => t('Edit view'),
'url' => Url::fromRoute('entity.view.edit_display_form', [
'view' => $view_id,
'display_id' => $display_id,
]),
'weight' => 50,
];
}
}
}
return $operations;
}
Functions
Title | Deprecated | Summary |
---|---|---|
views_ui_contextual_links_suppress | Sets a static variable for controlling whether contextual links are rendered. | |
views_ui_contextual_links_suppress_pop | Decrements the views_ui_contextual_links_suppress() static variable. | |
views_ui_contextual_links_suppress_push | Increments the views_ui_contextual_links_suppress() static variable. | |
views_ui_contextual_links_view_alter | Implements hook_contextual_links_view_alter(). | |
views_ui_entity_operation | Implements hook_entity_operation(). | |
views_ui_entity_type_build | Implements hook_entity_type_build(). | |
views_ui_help | Implements hook_help(). | |
views_ui_preprocess_views_view | Implements hook_preprocess_HOOK() for views templates. | |
views_ui_theme | Implements hook_theme(). | |
views_ui_theme_suggestions_views_ui_view_preview_section | Implements hook_theme_suggestions_HOOK(). | |
views_ui_truncate | in drupal:10.3.0 and is removed from drupal:12.0.0. Use \Drupal\Component\Utility\Unicode::truncate(). |
Truncate strings to a set length and provide a '...' if they truncated. |
views_ui_views_analyze | Implements hook_views_analyze(). | |
views_ui_views_plugins_display_alter | Implements hook_views_plugins_display_alter(). | |
views_ui_view_preview_section_display_category_links | Returns a link to editing a certain display setting. | |
views_ui_view_preview_section_handler_links | Returns contextual links for each handler of a certain section. | |
views_ui_view_preview_section_rows_links | Returns all contextual links for the main content part of the view. |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.