2

Does anyone know to how to get the destination in a template file?

At the moment I an getting the destination parameters in a preprocess function.

// Get destination params.
$variables['destination_params'] = \Drupal::destination()->getAsArray();

The template file uses the following code.

<p>
You can try <a href="{{ path('user.login', {}, {'query': destination_params}) }}">logging in</a> to see if you have access.
</p>
2
  • 2
    What's wrong about the current approach? I guess it's caching, right?
    – leymannx
    Aug 21, 2020 at 12:21
  • Primarily to use in places where it is easier to not use preprocess- e.g. views custom text, Display Suite Custom token field using twig etc. Aug 28, 2020 at 6:12

2 Answers 2

4

You can use path() function with '<current>' pseudo URI to generate current page relative URL.

For example:

{# in hard-coded path (bad practice) #}
<a href="/user/login?destination={{ path('<current>') }}" class="btn btn-sm btn-primary icon-before"><i class="fad fa-sign-in"></i> Sign-In</a>

{# more proper twig-like way #}
<p>
You can try <a href="{{ path('user.login', {}, {'query': {'destination': path('<current>') }}) }}">logging in</a> to see if you have access.
</p>

More about Drupal's twig built-in functions here: https://www.drupal.org/docs/theming-drupal/twig-in-drupal/functions-in-twig-templates

2
  • This seems fine, and bubbles cache metadata correctly (for the most parts - see below answer) but any extra query parameters are lost :-( Jul 6, 2021 at 1:16
  • As Joshua said, it would be good to include query string in this answer.
    – Christian
    Mar 23 at 4:56
0

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.