Initial Drupal 11 with DDEV setup
This commit is contained in:
90
web/core/modules/contextual/src/ContextualController.php
Normal file
90
web/core/modules/contextual/src/ContextualController.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\contextual;
|
||||
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
|
||||
use Drupal\Core\Render\RendererInterface;
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
|
||||
/**
|
||||
* Returns responses for Contextual module routes.
|
||||
*/
|
||||
class ContextualController implements ContainerInjectionInterface {
|
||||
|
||||
/**
|
||||
* The renderer.
|
||||
*
|
||||
* @var \Drupal\Core\Render\RendererInterface
|
||||
*/
|
||||
protected $renderer;
|
||||
|
||||
/**
|
||||
* Constructors a new ContextualController.
|
||||
*
|
||||
* @param \Drupal\Core\Render\RendererInterface $renderer
|
||||
* The renderer.
|
||||
*/
|
||||
public function __construct(RendererInterface $renderer) {
|
||||
$this->renderer = $renderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('renderer')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested rendered contextual links.
|
||||
*
|
||||
* Given a list of contextual links IDs, render them. Hence this must be
|
||||
* robust to handle arbitrary input.
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The Symfony request object.
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\JsonResponse
|
||||
* The JSON response.
|
||||
*
|
||||
* @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
|
||||
* Thrown when the request contains no ids.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @see contextual_preprocess()
|
||||
*/
|
||||
public function render(Request $request) {
|
||||
if (!$request->request->has('ids')) {
|
||||
throw new BadRequestHttpException('No contextual ids specified.');
|
||||
}
|
||||
$ids = $request->request->all('ids');
|
||||
|
||||
if (!$request->request->has('tokens')) {
|
||||
throw new BadRequestHttpException('No contextual ID tokens specified.');
|
||||
}
|
||||
$tokens = $request->request->all('tokens');
|
||||
|
||||
$rendered = [];
|
||||
foreach ($ids as $key => $id) {
|
||||
if (!isset($tokens[$key]) || !hash_equals($tokens[$key], Crypt::hmacBase64($id, Settings::getHashSalt() . \Drupal::service('private_key')->get()))) {
|
||||
throw new BadRequestHttpException('Invalid contextual ID specified.');
|
||||
}
|
||||
$element = [
|
||||
'#type' => 'contextual_links',
|
||||
'#contextual_links' => _contextual_id_to_links($id),
|
||||
];
|
||||
$rendered[$id] = $this->renderer->renderRoot($element);
|
||||
}
|
||||
|
||||
return new JsonResponse($rendered);
|
||||
}
|
||||
|
||||
}
|
||||
120
web/core/modules/contextual/src/Element/ContextualLinks.php
Normal file
120
web/core/modules/contextual/src/Element/ContextualLinks.php
Normal file
@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\contextual\Element;
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Component\Utility\SortArray;
|
||||
use Drupal\Core\Render\Attribute\RenderElement;
|
||||
use Drupal\Core\Render\Element\RenderElementBase;
|
||||
use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
* Provides a contextual_links element.
|
||||
*/
|
||||
#[RenderElement('contextual_links')]
|
||||
class ContextualLinks extends RenderElementBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getInfo() {
|
||||
return [
|
||||
'#pre_render' => [
|
||||
[static::class, 'preRenderLinks'],
|
||||
],
|
||||
'#theme' => 'links__contextual',
|
||||
'#links' => [],
|
||||
'#attributes' => ['class' => ['contextual-links']],
|
||||
'#attached' => [
|
||||
'library' => [
|
||||
'contextual/drupal.contextual-links',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-render callback: Builds a renderable array for contextual links.
|
||||
*
|
||||
* @param array $element
|
||||
* A renderable array containing a #contextual_links property, which is a
|
||||
* keyed array. Each key is the name of the group of contextual links to
|
||||
* render (based on the 'group' key in the *.links.contextual.yml files for
|
||||
* all enabled modules). The value contains an associative array containing
|
||||
* the following keys:
|
||||
* - route_parameters: The route parameters passed to the URL generator.
|
||||
* - metadata: Any additional data needed in order to alter the link.
|
||||
* @code
|
||||
* ['#contextual_links' => [
|
||||
* 'block' => [
|
||||
* 'route_parameters' => ['block' => 'system.menu-tools'],
|
||||
* ],
|
||||
* 'menu' => [
|
||||
* 'route_parameters' => ['menu' => 'tools'],
|
||||
* ],
|
||||
* ]]
|
||||
* @endcode
|
||||
*
|
||||
* @return array
|
||||
* A renderable array representing contextual links.
|
||||
*/
|
||||
public static function preRenderLinks(array $element) {
|
||||
// Retrieve contextual menu links.
|
||||
$items = [];
|
||||
|
||||
$contextual_links_manager = static::contextualLinkManager();
|
||||
|
||||
foreach ($element['#contextual_links'] as $group => $args) {
|
||||
$args += [
|
||||
'route_parameters' => [],
|
||||
'metadata' => [],
|
||||
];
|
||||
$items += $contextual_links_manager->getContextualLinksArrayByGroup($group, $args['route_parameters'], $args['metadata']);
|
||||
}
|
||||
|
||||
uasort($items, [SortArray::class, 'sortByWeightElement']);
|
||||
|
||||
// Transform contextual links into parameters suitable for links.html.twig.
|
||||
$links = [];
|
||||
foreach ($items as $class => $item) {
|
||||
$class = Html::getClass($class);
|
||||
$links[$class] = [
|
||||
'title' => $item['title'],
|
||||
'url' => Url::fromRoute($item['route_name'] ?? '', $item['route_parameters'] ?? [], $item['localized_options']),
|
||||
];
|
||||
}
|
||||
$element['#links'] = $links;
|
||||
|
||||
// Allow modules to alter the renderable contextual links element.
|
||||
static::moduleHandler()->alter('contextual_links_view', $element, $items);
|
||||
|
||||
// If there are no links, tell \Drupal::service('renderer')->render() to
|
||||
// abort rendering.
|
||||
if (empty($element['#links'])) {
|
||||
$element['#printed'] = TRUE;
|
||||
}
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the contextual link manager.
|
||||
*
|
||||
* @return \Drupal\Core\Menu\ContextualLinkManager
|
||||
* The contextual link manager service.
|
||||
*/
|
||||
protected static function contextualLinkManager() {
|
||||
return \Drupal::service('plugin.manager.menu.contextual_link');
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the module handler.
|
||||
*
|
||||
* @return \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
* The module handler service.
|
||||
*/
|
||||
protected static function moduleHandler() {
|
||||
return \Drupal::moduleHandler();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\contextual\Element;
|
||||
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Drupal\Core\Template\Attribute;
|
||||
use Drupal\Core\Render\Attribute\RenderElement;
|
||||
use Drupal\Core\Render\Element\RenderElementBase;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
|
||||
/**
|
||||
* Provides a contextual_links_placeholder element.
|
||||
*/
|
||||
#[RenderElement('contextual_links_placeholder')]
|
||||
class ContextualLinksPlaceholder extends RenderElementBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getInfo() {
|
||||
return [
|
||||
'#pre_render' => [
|
||||
[static::class, 'preRenderPlaceholder'],
|
||||
],
|
||||
'#id' => NULL,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-render callback: Renders a contextual links placeholder into #markup.
|
||||
*
|
||||
* Renders an empty (hence invisible) placeholder div with a data-attribute
|
||||
* that contains an identifier ("contextual id"), which allows the JavaScript
|
||||
* of the drupal.contextual-links library to dynamically render contextual
|
||||
* links.
|
||||
*
|
||||
* @param array $element
|
||||
* A structured array with #id containing a "contextual id".
|
||||
*
|
||||
* @return array
|
||||
* The passed-in element with a contextual link placeholder in '#markup'.
|
||||
*
|
||||
* @see _contextual_links_to_id()
|
||||
*/
|
||||
public static function preRenderPlaceholder(array $element) {
|
||||
$token = Crypt::hmacBase64($element['#id'], Settings::getHashSalt() . \Drupal::service('private_key')->get());
|
||||
$attribute = new Attribute([
|
||||
'data-contextual-id' => $element['#id'],
|
||||
'data-contextual-token' => $token,
|
||||
'data-drupal-ajax-container' => '',
|
||||
]);
|
||||
$element['#markup'] = new FormattableMarkup('<div@attributes></div>', ['@attributes' => $attribute]);
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
}
|
||||
124
web/core/modules/contextual/src/Hook/ContextualHooks.php
Normal file
124
web/core/modules/contextual/src/Hook/ContextualHooks.php
Normal file
@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\contextual\Hook;
|
||||
|
||||
use Drupal\Component\Serialization\Json;
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\Core\Hook\Attribute\Hook;
|
||||
|
||||
/**
|
||||
* Hook implementations for contextual.
|
||||
*/
|
||||
class ContextualHooks {
|
||||
|
||||
use StringTranslationTrait;
|
||||
|
||||
/**
|
||||
* Implements hook_toolbar().
|
||||
*/
|
||||
#[Hook('toolbar')]
|
||||
public function toolbar(): array {
|
||||
$items = [];
|
||||
$items['contextual'] = ['#cache' => ['contexts' => ['user.permissions']]];
|
||||
if (!\Drupal::currentUser()->hasPermission('access contextual links')) {
|
||||
return $items;
|
||||
}
|
||||
$items['contextual'] += [
|
||||
'#type' => 'toolbar_item',
|
||||
'tab' => [
|
||||
'#type' => 'html_tag',
|
||||
'#tag' => 'button',
|
||||
'#value' => $this->t('Edit'),
|
||||
'#attributes' => [
|
||||
'class' => [
|
||||
'toolbar-icon',
|
||||
'toolbar-icon-edit',
|
||||
],
|
||||
'aria-pressed' => 'false',
|
||||
'type' => 'button',
|
||||
],
|
||||
],
|
||||
'#wrapper_attributes' => [
|
||||
'class' => [
|
||||
'hidden',
|
||||
'contextual-toolbar-tab',
|
||||
],
|
||||
],
|
||||
'#attached' => [
|
||||
'library' => [
|
||||
'contextual/drupal.contextual-toolbar',
|
||||
],
|
||||
],
|
||||
];
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_page_attachments().
|
||||
*
|
||||
* Adds the drupal.contextual-links library to the page for any user who has
|
||||
* the 'access contextual links' permission.
|
||||
*
|
||||
* @see contextual_preprocess()
|
||||
*/
|
||||
#[Hook('page_attachments')]
|
||||
public function pageAttachments(array &$page): void {
|
||||
if (!\Drupal::currentUser()->hasPermission('access contextual links')) {
|
||||
return;
|
||||
}
|
||||
$page['#attached']['library'][] = 'contextual/drupal.contextual-links';
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_help().
|
||||
*/
|
||||
#[Hook('help')]
|
||||
public function help($route_name, RouteMatchInterface $route_match): ?string {
|
||||
switch ($route_name) {
|
||||
case 'help.page.contextual':
|
||||
$output = '';
|
||||
$output .= '<h2>' . $this->t('About') . '</h2>';
|
||||
$output .= '<p>' . $this->t('The Contextual links module gives users with the <em>Use contextual links</em> permission quick access to tasks associated with certain areas of pages on your site. For example, a menu displayed as a block has links to edit the menu and configure the block. For more information, see the <a href=":contextual">online documentation for the Contextual Links module</a>.', [':contextual' => 'https://www.drupal.org/docs/8/core/modules/contextual']) . '</p>';
|
||||
$output .= '<h2>' . $this->t('Uses') . '</h2>';
|
||||
$output .= '<dl>';
|
||||
$output .= '<dt>' . $this->t('Displaying contextual links') . '</dt>';
|
||||
$output .= '<dd>';
|
||||
$output .= $this->t('Contextual links for an area on a page are displayed using a contextual links button. There are two ways to make the contextual links button visible:');
|
||||
$output .= '<ol>';
|
||||
$sample_picture = [
|
||||
'#theme' => 'image',
|
||||
'#uri' => 'core/misc/icons/bebebe/pencil.svg',
|
||||
'#alt' => $this->t('contextual links button'),
|
||||
];
|
||||
$sample_picture = \Drupal::service('renderer')->render($sample_picture);
|
||||
$output .= '<li>' . $this->t('Hovering over the area of interest will temporarily make the contextual links button visible (which looks like a pencil in most themes, and is normally displayed in the upper right corner of the area). The icon typically looks like this: @picture', ['@picture' => $sample_picture]) . '</li>';
|
||||
$output .= '<li>' . $this->t('If you have the <a href=":toolbar">Toolbar module</a> installed, clicking the contextual links button in the toolbar (which looks like a pencil) will make all contextual links buttons on the page visible. Clicking this button again will toggle them to invisible.', [
|
||||
':toolbar' => \Drupal::moduleHandler()->moduleExists('toolbar') ? Url::fromRoute('help.page', [
|
||||
'name' => 'toolbar',
|
||||
])->toString() : '#',
|
||||
]) . '</li>';
|
||||
$output .= '</ol>';
|
||||
$output .= $this->t('Once the contextual links button for the area of interest is visible, click the button to display the links.');
|
||||
$output .= '</dd>';
|
||||
$output .= '</dl>';
|
||||
return $output;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_contextual_links_view_alter().
|
||||
*
|
||||
* @see \Drupal\contextual\Plugin\views\field\ContextualLinks::render()
|
||||
*/
|
||||
#[Hook('contextual_links_view_alter')]
|
||||
public function contextualLinksViewAlter(&$element, $items): void {
|
||||
if (isset($element['#contextual_links']['contextual'])) {
|
||||
$encoded_links = $element['#contextual_links']['contextual']['metadata']['contextual-views-field-links'];
|
||||
$element['#links'] = Json::decode(rawurldecode($encoded_links));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\contextual\Hook;
|
||||
|
||||
use Drupal\Core\Hook\Attribute\Hook;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
||||
/**
|
||||
* Hook implementations for contextual.
|
||||
*/
|
||||
class ContextualThemeHooks {
|
||||
|
||||
public function __construct(
|
||||
protected readonly AccountInterface $currentUser,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Implements hook_preprocess().
|
||||
*
|
||||
* @see \Drupal\contextual\Element\ContextualLinksPlaceholder
|
||||
* @see contextual_page_attachments()
|
||||
* @see \Drupal\contextual\ContextualController::render()
|
||||
*/
|
||||
#[Hook('preprocess')]
|
||||
public function preprocess(&$variables, $hook, $info): void {
|
||||
// Determine the primary theme function argument.
|
||||
if (!empty($info['variables'])) {
|
||||
$keys = array_keys($info['variables']);
|
||||
$key = $keys[0];
|
||||
}
|
||||
elseif (!empty($info['render element'])) {
|
||||
$key = $info['render element'];
|
||||
}
|
||||
if (!empty($key) && isset($variables[$key])) {
|
||||
$element = $variables[$key];
|
||||
}
|
||||
|
||||
if (isset($element) && is_array($element) && !empty($element['#contextual_links'])) {
|
||||
$variables['#cache']['contexts'][] = 'user.permissions';
|
||||
if ($this->currentUser->hasPermission('access contextual links')) {
|
||||
// Mark this element as potentially having contextual links attached to
|
||||
// it.
|
||||
$variables['attributes']['class'][] = 'contextual-region';
|
||||
|
||||
// Renders a contextual links placeholder unconditionally, thus not
|
||||
// breaking the render cache. Although the empty placeholder is rendered
|
||||
// for all users, contextual_page_attachments() only adds the asset
|
||||
// library for users with the 'access contextual links' permission, thus
|
||||
// preventing unnecessary HTTP requests for users without that
|
||||
// permission.
|
||||
$variables['title_suffix']['contextual_links'] = [
|
||||
'#type' => 'contextual_links_placeholder',
|
||||
'#id' => _contextual_links_to_id($element['#contextual_links']),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\contextual\Hook;
|
||||
|
||||
use Drupal\Core\Hook\Attribute\Hook;
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||
|
||||
/**
|
||||
* Hook implementations for contextual.
|
||||
*/
|
||||
class ContextualViewsHooks {
|
||||
|
||||
use StringTranslationTrait;
|
||||
|
||||
/**
|
||||
* Implements hook_views_data_alter().
|
||||
*/
|
||||
#[Hook('views_data_alter')]
|
||||
public function viewsDataAlter(&$data): void {
|
||||
$data['views']['contextual_links'] = [
|
||||
'title' => $this->t('Contextual Links'),
|
||||
'help' => $this->t('Display fields in a contextual links menu.'),
|
||||
'field' => [
|
||||
'id' => 'contextual_links',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\contextual\Plugin\views\field;
|
||||
|
||||
use Drupal\Component\Serialization\Json;
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Component\Utility\UrlHelper;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Routing\RedirectDestinationTrait;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\views\Attribute\ViewsField;
|
||||
use Drupal\views\Plugin\views\field\FieldPluginBase;
|
||||
use Drupal\views\ResultRow;
|
||||
|
||||
/**
|
||||
* Provides a handler that adds contextual links.
|
||||
*
|
||||
* @ingroup views_field_handlers
|
||||
*/
|
||||
#[ViewsField("contextual_links")]
|
||||
class ContextualLinks extends FieldPluginBase {
|
||||
|
||||
use RedirectDestinationTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function usesGroupBy() {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function defineOptions() {
|
||||
$options = parent::defineOptions();
|
||||
|
||||
$options['fields'] = ['default' => []];
|
||||
$options['destination'] = ['default' => 1];
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
|
||||
$all_fields = $this->view->display_handler->getFieldLabels();
|
||||
// Offer to include only those fields that follow this one.
|
||||
$field_options = array_slice($all_fields, 0, array_search($this->options['id'], array_keys($all_fields)));
|
||||
$form['fields'] = [
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => $this->t('Fields'),
|
||||
'#description' => $this->t('Fields to be included as contextual links.'),
|
||||
'#options' => $field_options,
|
||||
'#default_value' => $this->options['fields'],
|
||||
];
|
||||
$form['destination'] = [
|
||||
'#type' => 'select',
|
||||
'#title' => $this->t('Include destination'),
|
||||
'#description' => $this->t('Include a "destination" parameter in the link to return the user to the original view upon completing the contextual action.'),
|
||||
'#options' => [
|
||||
'0' => $this->t('No'),
|
||||
'1' => $this->t('Yes'),
|
||||
],
|
||||
'#default_value' => $this->options['destination'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function preRender(&$values) {
|
||||
// Add a row plugin css class for the contextual link.
|
||||
$class = 'contextual-region';
|
||||
if (!empty($this->view->style_plugin->options['row_class'])) {
|
||||
$this->view->style_plugin->options['row_class'] .= " $class";
|
||||
}
|
||||
else {
|
||||
$this->view->style_plugin->options['row_class'] = $class;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\views\Plugin\views\field\FieldPluginBase::render().
|
||||
*
|
||||
* Renders the contextual fields.
|
||||
*
|
||||
* @param \Drupal\views\ResultRow $values
|
||||
* The values retrieved from a single row of a view's query result.
|
||||
*
|
||||
* @see contextual_preprocess()
|
||||
* @see contextual_contextual_links_view_alter()
|
||||
*/
|
||||
public function render(ResultRow $values) {
|
||||
$links = [];
|
||||
foreach ($this->options['fields'] as $field) {
|
||||
$rendered_field = $this->view->style_plugin->getField($values->index, $field);
|
||||
if (empty($rendered_field)) {
|
||||
continue;
|
||||
}
|
||||
$title = $this->view->field[$field]->last_render_text;
|
||||
$path = '';
|
||||
if (!empty($this->view->field[$field]->options['alter']['path'])) {
|
||||
$path = $this->view->field[$field]->options['alter']['path'];
|
||||
}
|
||||
elseif (!empty($this->view->field[$field]->options['alter']['url']) && $this->view->field[$field]->options['alter']['url'] instanceof Url) {
|
||||
$path = $this->view->field[$field]->options['alter']['url']->toString();
|
||||
}
|
||||
if (!empty($title) && !empty($path)) {
|
||||
// Make sure that tokens are replaced for this paths as well.
|
||||
$tokens = $this->getRenderTokens([]);
|
||||
$path = strip_tags(Html::decodeEntities(strtr($path, $tokens)));
|
||||
|
||||
$links[$field] = [
|
||||
'href' => $path,
|
||||
'title' => $title,
|
||||
];
|
||||
if (!empty($this->options['destination'])) {
|
||||
$links[$field]['query'] = $this->getDestinationArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Renders a contextual links placeholder.
|
||||
if (!empty($links)) {
|
||||
$contextual_links = [
|
||||
'contextual' => [
|
||||
'',
|
||||
[],
|
||||
[
|
||||
'contextual-views-field-links' => UrlHelper::encodePath(Json::encode($links)),
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$element = [
|
||||
'#type' => 'contextual_links_placeholder',
|
||||
'#id' => _contextual_links_to_id($contextual_links),
|
||||
];
|
||||
return \Drupal::service('renderer')->render($element);
|
||||
}
|
||||
else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user