4

In a twig template you are able to get a relative path by using {{ path('entity.node.edit_form', {'node': nid }) }}. The path will be in current language.

Now I need to get the path in a specfic language. I thought I could use {{ path('entity.node.edit_form', {'node': nid }, {'language': langcode}) }} but this results an error if I set langcode to a string like DE. According to the api docs language has to be a language object. How can I accomplish this in twig?

2 Answers 2

6

For a twig only solution you can define a custom twig function path_lang(), which adds the language object to options, if a language code is provided as additional parameter:

src/TwigExtension.php:

<?php

namespace Drupal\mymodule;

use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Routing\UrlGeneratorInterface;

class TwigExtension extends \Twig_Extension {

  protected $languageManager;

  protected $urlGenerator;

  public function __construct(LanguageManagerInterface $language_manager, UrlGeneratorInterface $url_generator) {
    $this->languageManager = $language_manager;
    $this->urlGenerator = $url_generator;
  }

  public function getName() {
    return 'mymodule';
  }

  public function getFunctions() {
    return [
      new \Twig_SimpleFunction('path_lang', [$this, 'getPathLang']),
    ];
  }

  public function getPathLang($name, $parameters = [], $options = [], $langcode = '') {
    if (!empty($langcode)) {
      if ($language = $this->languageManager->getLanguage($langcode)) {
        $options['language'] = $language;
      }
    }
    return $this->urlGenerator->generateFromRoute($name, $parameters, $options);
  }
}

mymodule.services.yml:

services:
  mymodule.twig.extension:
    arguments: ['@language_manager', '@url_generator']
    class: Drupal\mymodule\TwigExtension
    tags:
      - { name: twig.extension }

In twig:

{{  path_lang('entity.node.edit_form', {'node': nid }, {}, 'en') }}
2
  • Thank you for introducing me into Twig extensions! It works like a charm and is reusable. Nevertheless I opened an feature request because I think this is a really common issue: drupal.org/node/2813099 Oct 7, 2016 at 7:40
  • @4k4 Can you explain the difference between parameters and options? Im having trouble getting a query string in the link. The official API doc doesnt explain it very well.
    – Jeff
    May 4, 2018 at 16:53
2

This won't work because I think that you need the language object and not only the langcode.

The best way to do this I think it's to do it in a THEME_preprocess_node in your yourtheme.theme file :

SOLUTION 1 (get translation of the node and then get the proper link) :

function yourtheme_preprocess_node(&$vars) {
    $node = &$vars['node'];
    // TO HAVE NODE URL IN ANY OF YOUR NODE TEMPLATES FOR CURRENT LANGUAGE
    $vars['node_url'] = $node->toUrl()->toString();
    // SOLUTION 1
    $node_de = $node->getTranslation('de');
    if ($node_de && is_object($node_de)) {
        $node_url = $node_de->toUrl()->toString();
        $vars['node_url_de'] = $node_url;
    }
}

SOLUTION 2 (get the url object of the node and then get translation of the url object) :

function yourtheme_preprocess_node(&$vars) {
    $node = &$vars['node'];
    // TO HAVE NODE URL IN ANY OF YOUR NODE TEMPLATES FOR CURRENT LANGUAGE
    $vars['node_url'] = $node->toUrl()->toString();
    // SOLUTION 2
    $language_manager = \Drupal::service('language_manager');
    $language_de = $language_manager->getLanguage('de');
    $urlNodeObject = $node->toUrl();
    $urlNodeObject->setOption('language', $language_de);
    // IF YOU WANT AN ABSOLUTE URL
    $urlNodeObject->setAbsolute();

    $vars['node_url_de'] = $urlNodeObject->toString();
}

Although I put $vars['node_url'] = $node->toUrl()->toString(); to print {{ node_url }} instead of {{ path('entity.node.edit_form', {'node': nid }) }} because I think it's better.

Then in your TWIG template you just have to print {{ node_url_de }} for your aliased german node link.

1
  • I had hoped that there is an easy non-preprocess way, because this twig is used inside a user defined text field of a views view. I may open a feature request issue to allow a simple language code string instead of the language object. Otherwise it is really cumbersome to get a language specific path in twig. Oct 6, 2016 at 12:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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