Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\Core\Render;
|
Chris@0
|
4
|
Chris@0
|
5 /**
|
Chris@0
|
6 * Defines an interface for turning a render array into a string.
|
Chris@0
|
7 */
|
Chris@0
|
8 interface RendererInterface {
|
Chris@0
|
9
|
Chris@0
|
10 /**
|
Chris@0
|
11 * Renders final HTML given a structured array tree.
|
Chris@0
|
12 *
|
Chris@0
|
13 * Calls ::render() in such a way that placeholders are replaced.
|
Chris@0
|
14 *
|
Chris@0
|
15 * Should therefore only be used in occasions where the final rendering is
|
Chris@0
|
16 * happening, just before sending a Response:
|
Chris@0
|
17 * - system internals that are responsible for rendering the final HTML
|
Chris@0
|
18 * - render arrays for non-HTML responses, such as feeds
|
Chris@0
|
19 *
|
Chris@0
|
20 * (Cannot be executed within another render context.)
|
Chris@0
|
21 *
|
Chris@0
|
22 * @param array $elements
|
Chris@0
|
23 * The structured array describing the data to be rendered.
|
Chris@0
|
24 *
|
Chris@0
|
25 * @return \Drupal\Component\Render\MarkupInterface
|
Chris@0
|
26 * The rendered HTML.
|
Chris@0
|
27 *
|
Chris@0
|
28 * @throws \LogicException
|
Chris@0
|
29 * When called from inside another renderRoot() call.
|
Chris@0
|
30 *
|
Chris@0
|
31 * @see \Drupal\Core\Render\RendererInterface::render()
|
Chris@0
|
32 */
|
Chris@0
|
33 public function renderRoot(&$elements);
|
Chris@0
|
34
|
Chris@0
|
35 /**
|
Chris@0
|
36 * Renders final HTML in situations where no assets are needed.
|
Chris@0
|
37 *
|
Chris@0
|
38 * Calls ::render() in such a way that placeholders are replaced.
|
Chris@0
|
39 *
|
Chris@0
|
40 * Useful for instance when rendering the values of tokens or emails, which
|
Chris@0
|
41 * need a render array being turned into a string, but do not need any of the
|
Chris@0
|
42 * bubbleable metadata (the attached assets and cache tags).
|
Chris@0
|
43 *
|
Chris@0
|
44 * Some of these are a relatively common use case and happen *within* a
|
Chris@0
|
45 * ::renderRoot() call, but that is generally highly problematic (and hence an
|
Chris@0
|
46 * exception is thrown when a ::renderRoot() call happens within another
|
Chris@0
|
47 * ::renderRoot() call). However, in this case, we only care about the output,
|
Chris@0
|
48 * not about the bubbling. Hence this uses a separate render context, to not
|
Chris@0
|
49 * affect the parent ::renderRoot() call.
|
Chris@0
|
50 *
|
Chris@0
|
51 * (Can be executed within another render context: it runs in isolation.)
|
Chris@0
|
52 *
|
Chris@0
|
53 * @param array $elements
|
Chris@0
|
54 * The structured array describing the data to be rendered.
|
Chris@0
|
55 *
|
Chris@0
|
56 * @return \Drupal\Component\Render\MarkupInterface
|
Chris@0
|
57 * The rendered HTML.
|
Chris@0
|
58 *
|
Chris@0
|
59 * @see \Drupal\Core\Render\RendererInterface::renderRoot()
|
Chris@0
|
60 * @see \Drupal\Core\Render\RendererInterface::render()
|
Chris@0
|
61 */
|
Chris@0
|
62 public function renderPlain(&$elements);
|
Chris@0
|
63
|
Chris@0
|
64 /**
|
Chris@0
|
65 * Renders final HTML for a placeholder.
|
Chris@0
|
66 *
|
Chris@0
|
67 * Renders the placeholder in isolation.
|
Chris@0
|
68 *
|
Chris@0
|
69 * @param string $placeholder
|
Chris@0
|
70 * An attached placeholder to render. (This must be a key of one of the
|
Chris@0
|
71 * values of $elements['#attached']['placeholders'].)
|
Chris@0
|
72 * @param array $elements
|
Chris@0
|
73 * The structured array describing the data to be rendered.
|
Chris@0
|
74 *
|
Chris@0
|
75 * @return array
|
Chris@0
|
76 * The updated $elements.
|
Chris@0
|
77 *
|
Chris@0
|
78 * @see \Drupal\Core\Render\RendererInterface::render()
|
Chris@0
|
79 */
|
Chris@0
|
80 public function renderPlaceholder($placeholder, array $elements);
|
Chris@0
|
81
|
Chris@0
|
82 /**
|
Chris@0
|
83 * Renders HTML given a structured array tree.
|
Chris@0
|
84 *
|
Chris@0
|
85 * Renderable arrays have two kinds of key/value pairs: properties and
|
Chris@0
|
86 * children. Properties have keys starting with '#' and their values influence
|
Chris@0
|
87 * how the array will be rendered. Children are all elements whose keys do not
|
Chris@0
|
88 * start with a '#'. Their values should be renderable arrays themselves,
|
Chris@0
|
89 * which will be rendered during the rendering of the parent array. The markup
|
Chris@0
|
90 * provided by the children is typically inserted into the markup generated by
|
Chris@0
|
91 * the parent array.
|
Chris@0
|
92 *
|
Chris@0
|
93 * An important aspect of rendering is caching the result, when appropriate.
|
Chris@0
|
94 * Because the HTML of a rendered item includes all of the HTML of the
|
Chris@0
|
95 * rendered children, caching it requires certain information to bubble up
|
Chris@0
|
96 * from child elements to their parents:
|
Chris@0
|
97 * - Cache contexts, so that the render cache is varied by every context that
|
Chris@0
|
98 * affects the rendered HTML. Because cache contexts affect the cache ID,
|
Chris@0
|
99 * and therefore must be resolved for cache hits as well as misses, it is
|
Chris@0
|
100 * up to the implementation of this interface to decide how to implement
|
Chris@0
|
101 * the caching of items whose children specify cache contexts not directly
|
Chris@0
|
102 * specified by the parent. \Drupal\Core\Render\Renderer implements this
|
Chris@0
|
103 * with a lazy two-tier caching strategy. Alternate strategies could be to
|
Chris@0
|
104 * not cache such parents at all or to cache them with the child elements
|
Chris@0
|
105 * replaced by placeholder tokens that are dynamically rendered after cache
|
Chris@0
|
106 * retrieval.
|
Chris@0
|
107 * - Cache tags, so that cached renderings are invalidated when site content
|
Chris@0
|
108 * or configuration that can affect that rendering changes.
|
Chris@0
|
109 * - Placeholders, with associated self-contained placeholder render arrays,
|
Chris@0
|
110 * for executing code to handle dynamic requirements that cannot be cached.
|
Chris@0
|
111 * A render context (\Drupal\Core\Render\RenderContext) can be used to perform
|
Chris@0
|
112 * bubbling; it is a stack of \Drupal\Core\Render\BubbleableMetadata objects.
|
Chris@0
|
113 *
|
Chris@0
|
114 * Additionally, whether retrieving from cache or not, it is important to
|
Chris@0
|
115 * know all of the assets (CSS and JavaScript) required by the rendered HTML,
|
Chris@0
|
116 * and this must also bubble from child to parent. Therefore,
|
Chris@0
|
117 * \Drupal\Core\Render\BubbleableMetadata includes that data as well.
|
Chris@0
|
118 *
|
Chris@0
|
119 * The process of rendering an element is recursive unless the element defines
|
Chris@0
|
120 * an implemented theme hook in #theme. During each call to
|
Chris@0
|
121 * Renderer::render(), the outermost renderable array (also known as an
|
Chris@0
|
122 * "element") is processed using the following steps:
|
Chris@0
|
123 * - If this element has already been printed (#printed = TRUE) or the user
|
Chris@0
|
124 * does not have access to it (#access = FALSE), then an empty string is
|
Chris@0
|
125 * returned.
|
Chris@0
|
126 * - If no render context is set yet, an exception is thrown. Otherwise,
|
Chris@0
|
127 * an empty \Drupal\Core\Render\BubbleableMetadata is pushed onto the
|
Chris@0
|
128 * render context.
|
Chris@0
|
129 * - If this element has #cache defined then the cached markup for this
|
Chris@0
|
130 * element will be returned if it exists in Renderer::render()'s cache. To
|
Chris@0
|
131 * use Renderer::render() caching, set the element's #cache property to an
|
Chris@0
|
132 * associative array with one or several of the following keys:
|
Chris@0
|
133 * - 'keys': An array of one or more keys that identify the element. If
|
Chris@0
|
134 * 'keys' is set, the cache ID is created automatically from these keys.
|
Chris@0
|
135 * - 'contexts': An array of one or more cache context IDs. These are
|
Chris@0
|
136 * converted to a final value depending on the request. (For instance,
|
Chris@0
|
137 * 'user' is mapped to the current user's ID.)
|
Chris@0
|
138 * - 'max-age': A time in seconds. Zero seconds means it is not cacheable.
|
Chris@0
|
139 * \Drupal\Core\Cache\Cache::PERMANENT means it is cacheable forever.
|
Chris@0
|
140 * - 'bin': Specify a cache bin to cache the element in. Default is
|
Chris@0
|
141 * 'default'.
|
Chris@0
|
142 * When there is a render cache hit, there is no rendering work left to be
|
Chris@0
|
143 * done, so the stack must be updated. The empty (and topmost) frame that
|
Chris@0
|
144 * was just pushed onto the stack is updated with all bubbleable rendering
|
Chris@0
|
145 * metadata from the element retrieved from render cache. Then, this stack
|
Chris@0
|
146 * frame is bubbled: the two topmost frames are popped from the stack,
|
Chris@0
|
147 * they are merged, and the result is pushed back onto the stack.
|
Chris@0
|
148 * However, also in case of a cache miss we have to do something. Note
|
Chris@0
|
149 * that a Renderer renders top-down, which means that we try to render a
|
Chris@0
|
150 * parent first, and we try to avoid the work of rendering the children by
|
Chris@0
|
151 * using the render cache. Though in this case, we are dealing with a
|
Chris@0
|
152 * cache miss. So a Renderer traverses down the tree, rendering all
|
Chris@0
|
153 * children. In doing so, the render stack is updated with the bubbleable
|
Chris@0
|
154 * metadata of the children. That means that once the children are
|
Chris@0
|
155 * rendered, we can render cache this element. But the cache ID may have
|
Chris@0
|
156 * *changed* at that point, because the children's cache contexts have
|
Chris@0
|
157 * been bubbled!
|
Chris@0
|
158 * It is for that case that we must store the current (pre-bubbling) cache
|
Chris@0
|
159 * ID, so that we can compare it with the new (post-bubbling) cache ID
|
Chris@0
|
160 * when writing to the cache. We store the current cache ID in
|
Chris@0
|
161 * $pre_bubbling_cid.
|
Chris@0
|
162 * - If this element has #type defined and the default attributes for this
|
Chris@0
|
163 * element have not already been merged in (#defaults_loaded = TRUE) then
|
Chris@0
|
164 * the defaults for this type of element, defined by an element plugin,
|
Chris@0
|
165 * are merged into the array. #defaults_loaded is set by functions that
|
Chris@0
|
166 * process render arrays and call the element info service before passing
|
Chris@0
|
167 * the array to Renderer::render(), such as form_builder() in the Form
|
Chris@0
|
168 * API.
|
Chris@0
|
169 * - If this element has #create_placeholder set to TRUE, and it has a
|
Chris@0
|
170 * #lazy_builder callback, then the element is replaced with another
|
Chris@0
|
171 * element that has only two properties: #markup and #attached. #markup
|
Chris@0
|
172 * will contain placeholder markup, and #attached contains the placeholder
|
Chris@0
|
173 * metadata, that will be used for replacing this placeholder. That
|
Chris@0
|
174 * metadata contains a very compact render array (containing only
|
Chris@0
|
175 * #lazy_builder and #cache) that will be rendered to replace the
|
Chris@0
|
176 * placeholder with its final markup. This means that when the
|
Chris@0
|
177 * #lazy_builder callback is called, it received a render array to add to
|
Chris@0
|
178 * that only contains #cache.
|
Chris@0
|
179 * - If this element has a #lazy_builder or an array of #pre_render
|
Chris@0
|
180 * functions defined, they are called sequentially to modify the element
|
Chris@0
|
181 * before rendering. #lazy_builder is preferred, since it allows for
|
Chris@0
|
182 * placeholdering (see previous step), but #pre_render is still supported.
|
Chris@0
|
183 * Both have their use case: #lazy_builder is for building a render array,
|
Chris@0
|
184 * #pre_render is for decorating an existing render array.
|
Chris@0
|
185 * After the #lazy_builder function is called, #lazy_builder is removed,
|
Chris@0
|
186 * and #built is set to TRUE.
|
Chris@0
|
187 * After the #lazy_builder and all #pre_render functions have been called,
|
Chris@0
|
188 * #printed is checked a second time in case a #lazy_builder or
|
Chris@0
|
189 * #pre_render function flags the element as printed. If #printed is set,
|
Chris@0
|
190 * we return early and hence no rendering work is left to be done,
|
Chris@0
|
191 * similarly to a render cache hit. Once again, the empty (and topmost)
|
Chris@0
|
192 * frame that was just pushed onto the stack is updated with all
|
Chris@0
|
193 * bubbleable rendering metadata from the element whose #printed = TRUE.
|
Chris@0
|
194 * Then, this stack frame is bubbled: the two topmost frames are popped
|
Chris@0
|
195 * from the stack, they are merged, and the result is pushed back onto the
|
Chris@0
|
196 * stack.
|
Chris@0
|
197 * - The child elements of this element are sorted by weight using uasort()
|
Chris@0
|
198 * in \Drupal\Core\Render\Element::children(). Since this is expensive,
|
Chris@0
|
199 * when passing already sorted elements to Renderer::render(), for example
|
Chris@0
|
200 * from a database query, set $elements['#sorted'] = TRUE to avoid sorting
|
Chris@0
|
201 * them a second time.
|
Chris@0
|
202 * - The main render phase to produce #children for this element takes
|
Chris@0
|
203 * place:
|
Chris@0
|
204 * - If this element has #theme defined and #theme is an implemented theme
|
Chris@0
|
205 * hook/suggestion then ThemeManagerInterface::render() is called and
|
Chris@0
|
206 * must render both the element and its children. If #render_children is
|
Chris@0
|
207 * set, ThemeManagerInterface::render() will not be called.
|
Chris@0
|
208 * #render_children is usually only set internally by
|
Chris@0
|
209 * ThemeManagerInterface::render() so that we can avoid the situation
|
Chris@0
|
210 * where Renderer::render() called from within a theme preprocess
|
Chris@0
|
211 * function creates an infinite loop.
|
Chris@0
|
212 * - If this element does not have a defined #theme, or the defined #theme
|
Chris@0
|
213 * hook is not implemented, or #render_children is set, then
|
Chris@0
|
214 * Renderer::render() is called recursively on each of the child
|
Chris@0
|
215 * elements of this element, and the result of each is concatenated onto
|
Chris@0
|
216 * #children. This is skipped if #children is not empty at this point.
|
Chris@0
|
217 * - Once #children has been rendered for this element, if #theme is not
|
Chris@0
|
218 * implemented and #markup is set for this element, #markup will be
|
Chris@0
|
219 * prepended to #children.
|
Chris@0
|
220 * - If this element has #states defined then JavaScript state information
|
Chris@0
|
221 * is added to this element's #attached attribute by
|
Chris@0
|
222 * drupal_process_states().
|
Chris@0
|
223 * - If this element has #attached defined then any required libraries,
|
Chris@0
|
224 * JavaScript, CSS, or other custom data are added to the current page by
|
Chris@0
|
225 * \Drupal\Core\Render\AttachmentsResponseProcessorInterface::processAttachments().
|
Chris@0
|
226 * - If this element has an array of #theme_wrappers defined and
|
Chris@0
|
227 * #render_children is not set, #children is then re-rendered by passing
|
Chris@0
|
228 * the element in its current state to ThemeManagerInterface::render()
|
Chris@0
|
229 * successively for each item in #theme_wrappers. Since #theme and
|
Chris@0
|
230 * #theme_wrappers hooks often define variables with the same names it is
|
Chris@0
|
231 * possible to explicitly override each attribute passed to each
|
Chris@0
|
232 * #theme_wrappers hook by setting the hook name as the key and an array
|
Chris@0
|
233 * of overrides as the value in #theme_wrappers array.
|
Chris@0
|
234 * For example, if we have a render element as follows:
|
Chris@0
|
235 * @code
|
Chris@0
|
236 * array(
|
Chris@0
|
237 * '#theme' => 'image',
|
Chris@0
|
238 * '#attributes' => array('class' => array('foo')),
|
Chris@0
|
239 * '#theme_wrappers' => array('container'),
|
Chris@0
|
240 * );
|
Chris@0
|
241 * @endcode
|
Chris@0
|
242 * and we need to pass the class 'bar' as an attribute for 'container', we
|
Chris@0
|
243 * can rewrite our element thus:
|
Chris@0
|
244 * @code
|
Chris@0
|
245 * array(
|
Chris@0
|
246 * '#theme' => 'image',
|
Chris@0
|
247 * '#attributes' => array('class' => array('foo')),
|
Chris@0
|
248 * '#theme_wrappers' => array(
|
Chris@0
|
249 * 'container' => array(
|
Chris@0
|
250 * '#attributes' => array('class' => array('bar')),
|
Chris@0
|
251 * ),
|
Chris@0
|
252 * ),
|
Chris@0
|
253 * );
|
Chris@0
|
254 * @endcode
|
Chris@0
|
255 * - If this element has an array of #post_render functions defined, they
|
Chris@0
|
256 * are called sequentially to modify the rendered #children. Unlike
|
Chris@0
|
257 * #pre_render functions, #post_render functions are passed both the
|
Chris@0
|
258 * rendered #children attribute as a string and the element itself.
|
Chris@0
|
259 * - If this element has #prefix and/or #suffix defined, they are
|
Chris@0
|
260 * concatenated to #children.
|
Chris@0
|
261 * - The rendering of this element is now complete. The next step will be
|
Chris@0
|
262 * render caching. So this is the perfect time to update the stack. At
|
Chris@0
|
263 * this point, children of this element (if any), have been rendered also,
|
Chris@0
|
264 * and if there were any, their bubbleable rendering metadata will have
|
Chris@0
|
265 * been bubbled up into the stack frame for the element that is currently
|
Chris@0
|
266 * being rendered. The render cache item for this element must contain the
|
Chris@0
|
267 * bubbleable rendering metadata for this element and all of its children.
|
Chris@0
|
268 * However, right now, the topmost stack frame (the one for this element)
|
Chris@0
|
269 * currently only contains the metadata for the children. Therefore, the
|
Chris@0
|
270 * topmost stack frame is updated with this element's metadata, and then
|
Chris@0
|
271 * the element's metadata is replaced with the metadata in the topmost
|
Chris@0
|
272 * stack frame. This element now contains all bubbleable rendering
|
Chris@0
|
273 * metadata for this element and all its children, so it's now ready for
|
Chris@0
|
274 * render caching.
|
Chris@0
|
275 * - If this element has #cache defined, the rendered output of this element
|
Chris@0
|
276 * is saved to Renderer::render()'s internal cache. This includes the
|
Chris@0
|
277 * changes made by #post_render.
|
Chris@0
|
278 * At the same time, if $pre_bubbling_cid is set, it is compared to the
|
Chris@0
|
279 * calculated cache ID. If they are different, then a redirecting cache
|
Chris@0
|
280 * item is created, containing the #cache metadata of the current element,
|
Chris@0
|
281 * and written to cache using the value of $pre_bubbling_cid as the cache
|
Chris@0
|
282 * ID. This ensures the pre-bubbling ("wrong") cache ID redirects to the
|
Chris@0
|
283 * post-bubbling ("right") cache ID.
|
Chris@0
|
284 * - If this element also has #cache_properties defined, all the array items
|
Chris@0
|
285 * matching the specified property names will be cached along with the
|
Chris@0
|
286 * element markup. If properties include children names, the system
|
Chris@0
|
287 * assumes only children's individual markup is relevant and ignores the
|
Chris@0
|
288 * parent markup. This approach is normally not needed and should be
|
Chris@0
|
289 * adopted only when dealing with very advanced use cases.
|
Chris@0
|
290 * - If this element has attached placeholders ([#attached][placeholders]),
|
Chris@0
|
291 * or any of its children has (which we would know thanks to the stack
|
Chris@0
|
292 * having been updated just before the render caching step), its
|
Chris@0
|
293 * placeholder element containing a #lazy_builder function is rendered in
|
Chris@0
|
294 * isolation. The resulting markup is used to replace the placeholder, and
|
Chris@0
|
295 * any bubbleable metadata is merged.
|
Chris@0
|
296 * Placeholders must be unique, to guarantee that for instance, samples of
|
Chris@0
|
297 * placeholders are not replaced as well.
|
Chris@0
|
298 * - Just before finishing the rendering of this element, this element's
|
Chris@0
|
299 * stack frame (the topmost one) is bubbled: the two topmost frames are
|
Chris@0
|
300 * popped from the stack, they are merged and the result is pushed back
|
Chris@0
|
301 * onto the stack.
|
Chris@0
|
302 * So if for instance this element was a child element, then a new frame
|
Chris@0
|
303 * was pushed onto the stack element at the beginning of rendering this
|
Chris@0
|
304 * element, it was updated when the rendering was completed, and now we
|
Chris@0
|
305 * merge it with the frame for the parent, so that the parent now has the
|
Chris@0
|
306 * bubbleable rendering metadata for its child.
|
Chris@0
|
307 * - #printed is set to TRUE for this element to ensure that it is only
|
Chris@0
|
308 * rendered once.
|
Chris@0
|
309 * - The final value of #children for this element is returned as the
|
Chris@0
|
310 * rendered output.
|
Chris@0
|
311 *
|
Chris@0
|
312 * @param array $elements
|
Chris@0
|
313 * The structured array describing the data to be rendered.
|
Chris@0
|
314 * @param bool $is_root_call
|
Chris@0
|
315 * (Internal use only.) Whether this is a recursive call or not. See
|
Chris@0
|
316 * ::renderRoot().
|
Chris@0
|
317 *
|
Chris@0
|
318 * @return \Drupal\Component\Render\MarkupInterface
|
Chris@0
|
319 * The rendered HTML.
|
Chris@0
|
320 *
|
Chris@0
|
321 * @throws \LogicException
|
Chris@0
|
322 * When called outside of a render context (i.e. outside of a renderRoot(),
|
Chris@0
|
323 * renderPlain() or executeInRenderContext() call).
|
Chris@0
|
324 * @throws \Exception
|
Chris@0
|
325 * If a #pre_render callback throws an exception, it is caught to mark the
|
Chris@0
|
326 * renderer as no longer being in a root render call, if any. Then the
|
Chris@0
|
327 * exception is rethrown.
|
Chris@0
|
328 *
|
Chris@0
|
329 * @see \Drupal\Core\Render\ElementInfoManagerInterface::getInfo()
|
Chris@0
|
330 * @see \Drupal\Core\Theme\ThemeManagerInterface::render()
|
Chris@0
|
331 * @see drupal_process_states()
|
Chris@0
|
332 * @see \Drupal\Core\Render\AttachmentsResponseProcessorInterface::processAttachments()
|
Chris@0
|
333 * @see \Drupal\Core\Render\RendererInterface::renderRoot()
|
Chris@0
|
334 */
|
Chris@0
|
335 public function render(&$elements, $is_root_call = FALSE);
|
Chris@0
|
336
|
Chris@0
|
337 /**
|
Chris@0
|
338 * Checks whether a render context is active.
|
Chris@0
|
339 *
|
Chris@0
|
340 * This is useful only in very specific situations to determine whether the
|
Chris@0
|
341 * system is already capable of collecting bubbleable metadata. Normally it
|
Chris@0
|
342 * should not be necessary to be concerned about this.
|
Chris@0
|
343 *
|
Chris@0
|
344 * @return bool
|
Chris@0
|
345 * TRUE if the renderer has a render context active, FALSE otherwise.
|
Chris@0
|
346 */
|
Chris@0
|
347 public function hasRenderContext();
|
Chris@0
|
348
|
Chris@0
|
349 /**
|
Chris@0
|
350 * Executes a callable within a render context.
|
Chris@0
|
351 *
|
Chris@0
|
352 * Only for very advanced use cases. Prefer using ::renderRoot() and
|
Chris@0
|
353 * ::renderPlain() instead.
|
Chris@0
|
354 *
|
Chris@0
|
355 * All rendering must happen within a render context. Within a render context,
|
Chris@0
|
356 * all bubbleable metadata is bubbled and hence tracked. Outside of a render
|
Chris@0
|
357 * context, it would be lost. This could lead to missing assets, incorrect
|
Chris@0
|
358 * cache variations (and thus security issues), insufficient cache
|
Chris@0
|
359 * invalidations, and so on.
|
Chris@0
|
360 *
|
Chris@0
|
361 * Any and all rendering must therefore happen within a render context, and it
|
Chris@0
|
362 * is this method that provides that.
|
Chris@0
|
363 *
|
Chris@0
|
364 * @param \Drupal\Core\Render\RenderContext $context
|
Chris@0
|
365 * The render context to execute the callable within.
|
Chris@0
|
366 * @param callable $callable
|
Chris@0
|
367 * The callable to execute.
|
Chris@0
|
368 *
|
Chris@0
|
369 * @return mixed
|
Chris@0
|
370 * The callable's return value.
|
Chris@0
|
371 *
|
Chris@0
|
372 * @throws \LogicException
|
Chris@0
|
373 * In case bubbling has failed, can only happen in case of broken code.
|
Chris@0
|
374 *
|
Chris@0
|
375 * @see \Drupal\Core\Render\RenderContext
|
Chris@0
|
376 * @see \Drupal\Core\Render\BubbleableMetadata
|
Chris@0
|
377 */
|
Chris@0
|
378 public function executeInRenderContext(RenderContext $context, callable $callable);
|
Chris@0
|
379
|
Chris@0
|
380 /**
|
Chris@0
|
381 * Merges the bubbleable rendering metadata o/t 2nd render array with the 1st.
|
Chris@0
|
382 *
|
Chris@0
|
383 * @param array $a
|
Chris@0
|
384 * A render array.
|
Chris@0
|
385 * @param array $b
|
Chris@0
|
386 * A render array.
|
Chris@0
|
387 *
|
Chris@0
|
388 * @return array
|
Chris@0
|
389 * The first render array, modified to also contain the bubbleable rendering
|
Chris@0
|
390 * metadata of the second render array.
|
Chris@0
|
391 *
|
Chris@0
|
392 * @see \Drupal\Core\Render\BubbleableMetadata
|
Chris@0
|
393 */
|
Chris@0
|
394 public function mergeBubbleableMetadata(array $a, array $b);
|
Chris@0
|
395
|
Chris@0
|
396 /**
|
Chris@0
|
397 * Adds a dependency on an object: merges its cacheability metadata.
|
Chris@0
|
398 *
|
Chris@0
|
399 * For instance, when a render array depends on some configuration, an entity,
|
Chris@0
|
400 * or an access result, we must make sure their cacheability metadata is
|
Chris@0
|
401 * present on the render array. This method makes doing that simple.
|
Chris@0
|
402 *
|
Chris@0
|
403 * @param array &$elements
|
Chris@0
|
404 * The render array to update.
|
Chris@0
|
405 * @param \Drupal\Core\Cache\CacheableDependencyInterface|mixed $dependency
|
Chris@0
|
406 * The dependency. If the object implements CacheableDependencyInterface,
|
Chris@0
|
407 * then its cacheability metadata will be used. Otherwise, the passed in
|
Chris@0
|
408 * object must be assumed to be uncacheable, so max-age 0 is set.
|
Chris@0
|
409 *
|
Chris@0
|
410 * @see \Drupal\Core\Cache\CacheableMetadata::createFromObject()
|
Chris@0
|
411 */
|
Chris@0
|
412 public function addCacheableDependency(array &$elements, $dependency);
|
Chris@0
|
413
|
Chris@0
|
414 }
|