Mercurial > hg > isophonics-drupal-site
comparison core/modules/contextual/contextual.module @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 129ea1e6d783 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 /** | |
4 * @file | |
5 * Adds contextual links to perform actions related to elements on a page. | |
6 */ | |
7 | |
8 use Drupal\Component\Serialization\Json; | |
9 use Drupal\Component\Utility\UrlHelper; | |
10 use Drupal\Core\Language\LanguageInterface; | |
11 use Drupal\Core\Routing\RouteMatchInterface; | |
12 | |
13 /** | |
14 * Implements hook_toolbar(). | |
15 */ | |
16 function contextual_toolbar() { | |
17 $items = []; | |
18 $items['contextual'] = [ | |
19 '#cache' => [ | |
20 'contexts' => [ | |
21 'user.permissions', | |
22 ], | |
23 ], | |
24 ]; | |
25 | |
26 if (!\Drupal::currentUser()->hasPermission('access contextual links')) { | |
27 return $items; | |
28 } | |
29 | |
30 $items['contextual'] += [ | |
31 '#type' => 'toolbar_item', | |
32 'tab' => [ | |
33 '#type' => 'html_tag', | |
34 '#tag' => 'button', | |
35 '#value' => t('Edit'), | |
36 '#attributes' => [ | |
37 'class' => ['toolbar-icon', 'toolbar-icon-edit'], | |
38 'aria-pressed' => 'false', | |
39 'type' => 'button', | |
40 ], | |
41 ], | |
42 '#wrapper_attributes' => [ | |
43 'class' => ['hidden', 'contextual-toolbar-tab'], | |
44 ], | |
45 '#attached' => [ | |
46 'library' => [ | |
47 'contextual/drupal.contextual-toolbar', | |
48 ], | |
49 ], | |
50 ]; | |
51 | |
52 return $items; | |
53 } | |
54 | |
55 /** | |
56 * Implements hook_page_attachments(). | |
57 * | |
58 * Adds the drupal.contextual-links library to the page for any user who has the | |
59 * 'access contextual links' permission. | |
60 * | |
61 * @see contextual_preprocess() | |
62 */ | |
63 function contextual_page_attachments(array &$page) { | |
64 if (!\Drupal::currentUser()->hasPermission('access contextual links')) { | |
65 return; | |
66 } | |
67 | |
68 $page['#attached']['library'][] = 'contextual/drupal.contextual-links'; | |
69 } | |
70 | |
71 /** | |
72 * Implements hook_help(). | |
73 */ | |
74 function contextual_help($route_name, RouteMatchInterface $route_match) { | |
75 switch ($route_name) { | |
76 case 'help.page.contextual': | |
77 $output = ''; | |
78 $output .= '<h3>' . t('About') . '</h3>'; | |
79 $output .= '<p>' . 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/documentation/modules/contextual']) . '</p>'; | |
80 $output .= '<h3>' . t('Uses') . '</h3>'; | |
81 $output .= '<dl>'; | |
82 $output .= '<dt>' . t('Displaying contextual links') . '</dt>'; | |
83 $output .= '<dd>'; | |
84 $output .= 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:'); | |
85 $output .= '<ol>'; | |
86 $sample_picture = [ | |
87 '#theme' => 'image', | |
88 '#uri' => 'core/misc/icons/bebebe/pencil.svg', | |
89 '#alt' => t('contextual links button') | |
90 ]; | |
91 $sample_picture = \Drupal::service('renderer')->render($sample_picture); | |
92 $output .= '<li>' . 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>'; | |
93 $output .= '<li>' . t('If you have the <a href=":toolbar">Toolbar module</a> enabled, 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')) ? \Drupal::url('help.page', ['name' => 'toolbar']) : '#']) . '</li>'; | |
94 $output .= '</ol>'; | |
95 $output .= t('Once the contextual links button for the area of interest is visible, click the button to display the links.'); | |
96 $output .= '</dd>'; | |
97 $output .= '</dl>'; | |
98 return $output; | |
99 } | |
100 } | |
101 | |
102 /** | |
103 * Implements hook_preprocess(). | |
104 * | |
105 * @see contextual_pre_render_placeholder() | |
106 * @see contextual_page_attachments() | |
107 * @see \Drupal\contextual\ContextualController::render() | |
108 */ | |
109 function contextual_preprocess(&$variables, $hook, $info) { | |
110 $variables['#cache']['contexts'][] = 'user.permissions'; | |
111 if (!\Drupal::currentUser()->hasPermission('access contextual links')) { | |
112 return; | |
113 } | |
114 | |
115 // Determine the primary theme function argument. | |
116 if (!empty($info['variables'])) { | |
117 $keys = array_keys($info['variables']); | |
118 $key = $keys[0]; | |
119 } | |
120 elseif (!empty($info['render element'])) { | |
121 $key = $info['render element']; | |
122 } | |
123 if (!empty($key) && isset($variables[$key])) { | |
124 $element = $variables[$key]; | |
125 } | |
126 | |
127 if (isset($element) && is_array($element) && !empty($element['#contextual_links'])) { | |
128 // Mark this element as potentially having contextual links attached to it. | |
129 $variables['attributes']['class'][] = 'contextual-region'; | |
130 | |
131 // Renders a contextual links placeholder unconditionally, thus not breaking | |
132 // the render cache. Although the empty placeholder is rendered for all | |
133 // users, contextual_page_attachments() only adds the asset library for | |
134 // users with the 'access contextual links' permission, thus preventing | |
135 // unnecessary HTTP requests for users without that permission. | |
136 $variables['title_suffix']['contextual_links'] = [ | |
137 '#type' => 'contextual_links_placeholder', | |
138 '#id' => _contextual_links_to_id($element['#contextual_links']), | |
139 ]; | |
140 } | |
141 } | |
142 | |
143 /** | |
144 * Implements hook_contextual_links_view_alter(). | |
145 * | |
146 * @see \Drupal\contextual\Plugin\views\field\ContextualLinks::render() | |
147 */ | |
148 function contextual_contextual_links_view_alter(&$element, $items) { | |
149 if (isset($element['#contextual_links']['contextual'])) { | |
150 $encoded_links = $element['#contextual_links']['contextual']['metadata']['contextual-views-field-links']; | |
151 $element['#links'] = Json::decode(rawurldecode($encoded_links)); | |
152 } | |
153 } | |
154 | |
155 /** | |
156 * Serializes #contextual_links property value array to a string. | |
157 * | |
158 * Examples: | |
159 * - node:node=1:langcode=en | |
160 * - views_ui_edit:view=frontpage:location=page&view_name=frontpage&view_display_id=page_1&langcode=en | |
161 * - menu:menu=tools:langcode=en|block:block=bartik.tools:langcode=en | |
162 * | |
163 * So, expressed in a pattern: | |
164 * <group>:<route parameters>:<metadata> | |
165 * | |
166 * The route parameters and options are encoded as query strings. | |
167 * | |
168 * @param array $contextual_links | |
169 * The $element['#contextual_links'] value for some render element. | |
170 * | |
171 * @return string | |
172 * A serialized representation of a #contextual_links property value array for | |
173 * use in a data- attribute. | |
174 */ | |
175 function _contextual_links_to_id($contextual_links) { | |
176 $ids = []; | |
177 $langcode = \Drupal::languageManager()->getCurrentLanguage(LanguageInterface::TYPE_URL)->getId(); | |
178 foreach ($contextual_links as $group => $args) { | |
179 $route_parameters = UrlHelper::buildQuery($args['route_parameters']); | |
180 $args += ['metadata' => []]; | |
181 // Add the current URL language to metadata so a different ID will be | |
182 // computed when URLs vary by language. This allows to store different | |
183 // language-aware contextual links on the client side. | |
184 $args['metadata'] += ['langcode' => $langcode]; | |
185 $metadata = UrlHelper::buildQuery($args['metadata']); | |
186 $ids[] = "{$group}:{$route_parameters}:{$metadata}"; | |
187 } | |
188 return implode('|', $ids); | |
189 } | |
190 | |
191 /** | |
192 * Unserializes the result of _contextual_links_to_id(). | |
193 * | |
194 * @see _contextual_links_to_id | |
195 * | |
196 * @param string $id | |
197 * A serialized representation of a #contextual_links property value array. | |
198 * | |
199 * @return array | |
200 * The value for a #contextual_links property. | |
201 */ | |
202 function _contextual_id_to_links($id) { | |
203 $contextual_links = []; | |
204 $contexts = explode('|', $id); | |
205 foreach ($contexts as $context) { | |
206 list($group, $route_parameters_raw, $metadata_raw) = explode(':', $context); | |
207 parse_str($route_parameters_raw, $route_parameters); | |
208 $metadata = []; | |
209 parse_str($metadata_raw, $metadata); | |
210 $contextual_links[$group] = [ | |
211 'route_parameters' => $route_parameters, | |
212 'metadata' => $metadata, | |
213 ]; | |
214 } | |
215 return $contextual_links; | |
216 } |