Adding this here which expands on the answer given here by @MiSHuTka
(that answer work perfectly for most scenarios with cache data)
Noting that both answers will not provide any extra query parameters in the destination
query parameter. (if you wanted them to persist)
Sometimes you need to add the html link to an render array item instead of the template itself to get cache data to work correctly (I believe this has something to do with #theme_wrappers
and #theme
on the same render array?). So use '#type': 'inline_template'
+ verbatim
tag to force string, so it be reparsed to bubble cache data.
{% set login_link %}
{# verbatim used to force a string, so it can be reparsed as twig later on, keeping cache metadata in the correct context #}
{% verbatim %}
<a href="{{ path('user.login', {}, {'query': {'destination': path('<current>')} }) }}">{{ 'Login'|t }}</a>
{% endverbatim %}
{% endset %}
{% set extra_render = {'#type': 'inline_template', '#template': login_link} %}
Use like so:
{% extends "field.html.twig" %}
{% for key, item in items %}
{# Add markup to the the render array - assume `extra_render` variable. #}
{% set item_content = item.content|merge( {'extra_render': extra_render} ) %}
{% set item = item|merge({'content': item_content }) %}
{# Prepend to render array #}
{% set items = {(key): item} + items %}
{% endfor %}
Edit:
I have noted that for some reason. If variable is printed via twig white space control {{- render_var -}}
then the verbatim
string is not rendered, just printed as is. (regular set/end set works fine but renders too early of course for caching)
Solution: Use inline_template
+ #context: _context
.
E.g. {% set extra_render = {'#type': 'inline_template', '#template': mysetverbatimstring, '#context': _context }
For {{- render_var -}}
- twig white space control
@see https://www.drupal.org/docs/theming-drupal/twig-in-drupal/comparison-of-phptemplate-and-twig-theming-paradigms#whitespace
For _context
@see https://twig.symfony.com/doc/2.x/templates.html#global-variables