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?

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') }}
  • 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 – Philipp Michael Oct 7 '16 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 '18 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.

  • 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. – Philipp Michael Oct 6 '16 at 12:52

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.