I have a Link field named field_my_link (machine name).

Within a Twig template I can get the link's URL value with this:

{{ node.field_my_link.uri }}

If inside the Link's URL there is an external URL, e.g. http://example.com it works good.

But, if inside the Link's URL there is stored an internal URL, e.g. "/node/11", I get a value like this:

"internal:/node/11"

with the "internal:" prefix.

How can I get the valid URL?

For example, if the link's URL is "http://example.com" I want "http://example.com" (this already works), if the link's URL is "/node/11" I want the relative URL "/node/11", if the link's URL is "<front>" I want the URL "/", etc.


EDIT

I can get the value I want within a PHP preprocess function, using this:

$url = $variables['node']->get('field_my_link')->first()->getUrl();

How can I access the same value within the Twig template?

I know I can do this within the preprocess function:

$variables['my_url'] = $url;

Then access the url within Twig using {{ my_url }}, but I would avoid to write a preprocess function each time I have a link field.

up vote 30 down vote accepted

Your PHP from your latest edit would translate into twig like this:

{{ node.field_my_link.0.url }}

This works like this, 0 returns the first item of the field item list, url gets the url object and because twig will cast this object as a string this will call the magic method toString() and will output the url as a string value.

You only need to use url, because twig looks automatically for the method getxyz() if there is no property with that name xyz.

  • Thank you. Now I make a test with this function. Do you know if can I use this function also on links' URIs? What happen if node.field_my_link.uri is an external url like http://www.example.com? – Andrea Apr 26 '16 at 12:25
  • 1
    I tried with file_url(node.field_my_link.uri), and if node.field_my_link.uri is "http://www.example.com" it works (it leaves the url unchanged), but if node.field_my_link.uri is "internal:/" the function returns "/internal%3A/" (instead of "/").. – Andrea Apr 26 '16 at 12:32
  • I just saw your edit.. Sadly it doesn't works, the code node.field_my_link.entity.uri.value returns a null value.. Any other ideas? – Andrea Apr 30 '16 at 7:32
  • @Andrea, I edited my answer. – 4k4 Apr 30 '16 at 11:27
  • 1
    Yeah, it works. The syntax is a bit scary, but it does its job. – Andrea Apr 30 '16 at 11:53

You can access the render array element directly, in your case:

{{ node.field_my_link[0]['#url'] }}

I had to do this on a Link Field in a Block. This worked well:

{{ content.field_my_link[0]['#url']|render }}
  • 1
    It is also fine to use {{ content.field_my_link[0]['#url'] }} without render, as in twig template, render array are automatically rendered when printed. – eric.chenchao Jun 6 '17 at 2:35

You have to cover both cases: external and internal URLs.

First let's check if the URL is external and simply print its *.uri.

Else if it's internal we have to wire its route name and parameters through Drupal's path($name, $parameters, $options) function.

{% if node.field_link.0.url.external %}
  <a href="{{ node.field_link.uri }}">
    {{ node.field_link.title }}
  </a>
{% else %}
  <a href="{{ path(node.field_link.0.url.routeName, node.field_link.0.url.routeParameters) }}">
    {{ node.field_link.title }}
  </a>
{% endif %}
  • 2
    Thank you, this is exactly what I needed: get the url from a link field as a string: {% set url = path(node.field_link.0.url.routeName, node.field_link.0.url.routeParameters) %} Then I can create a custom link:` <a href="{{ url }}" class="mycustomclass">custom link text</a> No preprocess needed and no need to go via content.field_link, so no need to do anything in the 'Manage display' for the link field just to get the url. – user33560 Mar 1 at 8:56

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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