Mercurial > hg > isophonics-drupal-site
view core/modules/settings_tray/settings_tray.module @ 19:fa3358dc1485 tip
Add ndrum files
author | Chris Cannam |
---|---|
date | Wed, 28 Aug 2019 13:14:47 +0100 |
parents | af1871eacc83 |
children |
line wrap: on
line source
<?php /** * @file * Allows configuring blocks and other configuration from the site front-end. */ use Drupal\Core\Url; use Drupal\Core\Asset\AttachedAssetsInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\block\entity\Block; use Drupal\block\BlockInterface; use Drupal\settings_tray\Block\BlockEntitySettingTrayForm; /** * Implements hook_help(). */ function settings_tray_help($route_name, RouteMatchInterface $route_match) { switch ($route_name) { case 'help.page.settings_tray': $output = '<h3>' . t('About') . '</h3>'; $output .= '<p>' . t('The Settings Tray module allows users with the <a href=":administer_block_permission">Administer blocks</a> and <a href=":contextual_permission">Use contextual links</a> permissions to edit blocks without visiting a separate page. For more information, see the <a href=":handbook_url">online documentation for the Settings Tray module</a>.', [':handbook_url' => 'https://www.drupal.org/documentation/modules/settings_tray', ':administer_block_permission' => Url::fromRoute('user.admin_permissions', [], ['fragment' => 'module-block'])->toString(), ':contextual_permission' => Url::fromRoute('user.admin_permissions', [], ['fragment' => 'module-contextual'])->toString()]) . '</p>'; $output .= '<h3>' . t('Uses') . '</h3>'; $output .= '<dl>'; $output .= '<dt>' . t('Editing blocks in place') . '</dt>'; $output .= '<dd>'; $output .= '<p>' . t('To edit blocks in place, either click the <strong>Edit</strong> button in the toolbar and then click on the block, or choose "Quick edit" from the block\'s contextual link. (See the <a href=":contextual">Contextual Links module help</a> for more information about how to use contextual links.)', [':contextual' => Url::fromRoute('help.page', ['name' => 'contextual'])->toString()]) . '</p>'; $output .= '<p>' . t('The Settings Tray for the block will open in a sidebar, with a compact form for configuring what the block shows.') . '</p>'; $output .= '<p>' . t('Save the form and the changes will be immediately visible on the page.') . '</p>'; $output .= '</dd>'; $output .= '</dl>'; return ['#markup' => $output]; } } /** * Implements hook_contextual_links_view_alter(). * * Change Configure Blocks into off_canvas links. */ function settings_tray_contextual_links_view_alter(&$element, $items) { if (isset($element['#links']['settings-trayblock-configure'])) { // Place settings_tray link first. $settings_tray_link = $element['#links']['settings-trayblock-configure']; unset($element['#links']['settings-trayblock-configure']); $element['#links'] = ['settings-trayblock-configure' => $settings_tray_link] + $element['#links']; // If this is content block change title to avoid duplicate "Quick Edit". if (isset($element['#links']['block-contentblock-edit'])) { $element['#links']['settings-trayblock-configure']['title'] = t('Quick edit settings'); } $element['#attached']['library'][] = 'core/drupal.dialog.off_canvas'; } } /** * Checks if a block has overrides. * * @param \Drupal\block\BlockInterface $block * The block to check for overrides. * * @return bool * TRUE if the block has overrides otherwise FALSE. * * @internal */ function _settings_tray_has_block_overrides(BlockInterface $block) { // @todo Replace the following with $block->hasOverrides() in https://www.drupal.org/project/drupal/issues/2910353 // and remove this function. return \Drupal::config($block->getEntityType()->getConfigPrefix() . '.' . $block->id())->hasOverrides(); } /** * Implements hook_block_view_alter(). */ function settings_tray_block_view_alter(array &$build) { if (isset($build['#contextual_links']['block'])) { // Ensure that contextual links vary by whether the block has config overrides // or not. // @see _contextual_links_to_id() $build['#contextual_links']['block']['metadata']['has_overrides'] = _settings_tray_has_block_overrides($build['#block']) ? 1 : 0; } // Force a new 'data-contextual-id' attribute on blocks when this module is // enabled so as not to reuse stale data cached client-side. // @todo Remove when https://www.drupal.org/node/2773591 is fixed. $build['#contextual_links']['settings_tray'] = [ 'route_parameters' => [], ]; } /** * Implements hook_entity_type_build(). */ function settings_tray_entity_type_build(array &$entity_types) { /* @var $entity_types \Drupal\Core\Entity\EntityTypeInterface[] */ $entity_types['block'] ->setFormClass('settings_tray', BlockEntitySettingTrayForm::class) ->setLinkTemplate('settings_tray-form', '/admin/structure/block/manage/{block}/settings-tray'); } /** * Implements hook_preprocess_HOOK() for block templates. */ function settings_tray_preprocess_block(&$variables) { // Only blocks that have a settings_tray form and have no configuration // overrides will have a "Quick Edit" link. We could wait for the contextual // links to be initialized on the client side, and then add the class and // data- attribute below there (via JavaScript). But that would mean that it // would be impossible to show Settings Tray's clickable regions immediately // when the page loads. When latency is high, this will cause flicker. // @see \Drupal\settings_tray\Access\BlockPluginHasSettingsTrayFormAccessCheck /** @var \Drupal\settings_tray\Access\BlockPluginHasSettingsTrayFormAccessCheck $access_checker */ $access_checker = \Drupal::service('access_check.settings_tray.block.settings_tray_form'); /** @var \Drupal\Core\Block\BlockManagerInterface $block_plugin_manager */ $block_plugin_manager = \Drupal::service('plugin.manager.block'); /** @var \Drupal\Core\Block\BlockPluginInterface $block_plugin */ $block_plugin = $block_plugin_manager->createInstance($variables['plugin_id']); if (isset($variables['elements']['#contextual_links']['block']['route_parameters']['block'])) { $block = Block::load($variables['elements']['#contextual_links']['block']['route_parameters']['block']); if ($access_checker->accessBlockPlugin($block_plugin)->isAllowed() && !_settings_tray_has_block_overrides($block)) { // Add class and attributes to all blocks to allow Javascript to target. $variables['attributes']['class'][] = 'settings-tray-editable'; $variables['attributes']['data-drupal-settingstray'] = 'editable'; } } } /** * Implements hook_toolbar_alter(). * * Alters the 'contextual' toolbar tab if it exists (meaning the user is allowed * to use contextual links) and if they can administer blocks. * * @todo Remove the "administer blocks" requirement in * https://www.drupal.org/node/2822965. * * @see contextual_toolbar() */ function settings_tray_toolbar_alter(&$items) { $items['contextual']['#cache']['contexts'][] = 'user.permissions'; if (isset($items['contextual']['tab']) && \Drupal::currentUser()->hasPermission('administer blocks')) { $items['contextual']['#weight'] = -1000; $items['contextual']['#attached']['library'][] = 'settings_tray/drupal.settings_tray'; $items['contextual']['tab']['#attributes']['data-drupal-settingstray'] = 'toggle'; // Set a class on items to mark whether they should be active in edit mode. // @todo Create a dynamic method for modules to set their own items. // https://www.drupal.org/node/2784589. $edit_mode_items = ['contextual', 'block_place']; foreach ($items as $key => $item) { if (!in_array($key, $edit_mode_items) && (!isset($items[$key]['#wrapper_attributes']['class']) || !in_array('hidden', $items[$key]['#wrapper_attributes']['class']))) { $items[$key]['#wrapper_attributes']['class'][] = 'edit-mode-inactive'; } } } } /** * Implements hook_block_alter(). * * Ensures every block plugin definition has an 'settings_tray' form specified. * * @see \Drupal\settings_tray\Access\BlockPluginHasSettingsTrayFormAccessCheck */ function settings_tray_block_alter(&$definitions) { foreach ($definitions as &$definition) { // If a block plugin does not define its own 'settings_tray' form, use the // plugin class itself. if (!isset($definition['forms']['settings_tray'])) { $definition['forms']['settings_tray'] = $definition['class']; } } } /** * Implements hook_css_alter(). */ function settings_tray_css_alter(&$css, AttachedAssetsInterface $assets) { // @todo Remove once conditional ordering is introduced in // https://www.drupal.org/node/1945262. $path = drupal_get_path('module', 'settings_tray') . '/css/settings_tray.theme.css'; if (isset($css[$path])) { // Use 200 to come after CSS_AGGREGATE_THEME. $css[$path]['group'] = 200; } }