22

I'm trying to retrieve the URL and the Title values of a Link field in Drupal 8.

In my custom controller, I retrieve the nodes with:

$storage = \Drupal::entityManager()->getStorage('node');
$nids = $storage->getQuery()
    ->condition('type', 'partners')
    ->condition('status', 1)
    ->execute();

$partners = $storage->loadMultiple($nids);

When I loop throught all my nodes, to preprocess vars I'll give to my view, I would like to retrieve the URL and the Title.

foreach ($partners as $key => $partner) {
    $variables['partners'][] = array(
        'image' => $partner->field_logo->entity->url(),
        'url'   => $partner->field_link->value, // Can't retrieve values of link field
    );
}

Unfortunately, I don't found how to retrieve the URL and the Title of field_link.

Thanks for your help.

mymiracl
  • 583
  • 1
  • 16
  • 24
Kevin Wenger
  • 1,484
  • 1
  • 13
  • 29

11 Answers11

43

At the node level, inside your Twig template you can use:

{{ content.field_link.0['#url'] }} & {{ content.field_link.0['#title'] }}

For example:

<a href="{{ content.field_link.0['#url'] }}">{{ content.field_link.0['#title'] }}</a>

field_link being the name of the link field in question.

Daniel Dewhurst
  • 2,533
  • 2
  • 21
  • 39
Mark Conroy
  • 689
  • 7
  • 11
  • 1
    I have overridden `views-view-fields.html.twig` where I want to extract the `URL` part from `title` and assign it to a separate link. I tried two wild gueses: `{{ fields.title.content.0['#url'] }}` and `{{ fields.title.content['#url'] }}`. However none of those worked :) How I can do this? – Subrata Sarkar Dec 01 '16 at 11:57
  • 1
    I think you need to `|render ` the field, this seems to work for me: `{{ fields.title.content.0['#url']|render }}` to get the actual URL – bdanin Sep 26 '17 at 21:10
  • what if we are not in the node level instead we created the view and used a block? – Omer Sep 07 '18 at 05:33
  • Also tried the above render technique ... didn't work :( – Omer Sep 07 '18 at 06:11
  • @SubrataSarkar I think you can do this by adding a field path:content. – Jignesh Rawal Nov 13 '18 at 12:32
  • @omer you can use {{content.field_link.0['#url']}} at block level (in block--bundle--block-name.html.twig). Hope this helps! – Rob Hern Mar 26 '20 at 11:11
15

I just found the solution ...

$partner->field_lien->uri // The url
$partner->field_lien->title // The title

My bad, hope it could help someone.

Kevin Wenger
  • 1,484
  • 1
  • 13
  • 29
12

Just to piggyback on the above, if you have an external link,

$node->field_name->uri

Will give you the URL, but if it's an internal you may need to tweak a bit more:

use Drupal\Core\Url;

$mylink = Url::fromUri($node->field_name[0]->uri);
$mylink->toString();
Greg
  • 121
  • 1
  • 2
  • 3
    Thanks for your contribution. In fact, you can retrieve the direct url with **$node->field_name->entity->url();** Hope I help you. – Kevin Wenger Apr 21 '16 at 10:03
  • @KevinWenger, are you sure? I get a nullpointer exception if I try your code on a field collection link field. – Andreas Jul 03 '19 at 20:29
  • It depends the type of `field_name`. In my example, if your `field_name` is an *entityreference* (link to node, taxonomy or any other entity) then it would works. Otherwise, indeed for a standard link field you should do `$node->field_name->first()->uri` – Kevin Wenger Jul 04 '19 at 07:56
3

Updated for Drupal 8

To get the url all you need to do is:

{{ content.field_link_name[0]['#url'] }}

To get the link text:

{{ content.field_link_name[0]['#title'] }}
Vishal Rao
  • 872
  • 1
  • 7
  • 18
3

If you want to do this in a field template instead of a node template do this:

{% for item in items %}
  {{ item.content['#url'] }}
  {{ item.content['#title'] }}
{% endfor %}

Alternately, if this is not a multi-value field you can just do this instead:

{{ items|first.content['#url'] }}
{{ items|first.content['#title'] }}
Kevin Wenger
  • 1,484
  • 1
  • 13
  • 29
mel-miller
  • 31
  • 2
  • This isn't working for me. {{item.content}} shows the linked file. However {{ item.content['#url'] }} isn't giving the url in field--field_down.html.twig for me. – homersheineken Mar 27 '20 at 15:43
2

You can render either the uri or text of a link field directly in the twig template. In the case of a node you can use either of the following within the twig template file (assumes the machine name of your link field is field_link):

{{ node.field_link.uri }}

{{ node.field_link.title }} 
Benjen
  • 2,835
  • 5
  • 28
  • 42
  • Weird, other solutions like `{{ entity.field_link[0]['#url'] }}` was working on certain `node—view--xxx` but not all views. Your solution works perfectly well in all cases. – Sébastien Gicquel Mar 28 '18 at 11:35
1

This one works for me in twig:

content.field_link_name.0['#title']        // title
content.field_link_name.0['#url_title']    // url value

*you should use: "Separate link text and URL" widget in display

zanvidmar
  • 361
  • 4
  • 13
  • This one worked me using a paragraphs with a link field and i configured the widget to display in the way mentioned. – Robbiegod Mar 27 '20 at 18:50
1

If you're doing it in a preprocess, I'd suggest to base your code on LinkSeparateFormatter.php. It shows the idea on how to get the title from the link field. Here's a way to do it.

use Drupal\Component\Utility\Unicode;

//...

$field_link = $entity->field_link->first();
$link_url = $field_link->getUrl();
$link_data = $field_link->toArray();
// If you want to truncate the url
$link_title = Unicode::truncate($link_url->toString(), 40, FALSE, TRUE);
if(!empty($link_data['title'])){
  // You could truncate here as well
  $link_title = $link_data['title'];
}
$variables['content'] = [
  '#type' => 'link',
  '#url' => $link_url,
  '#title' => $link_title,
];
JFC
  • 575
  • 11
  • 25
0

I am doing this link separation for ECK fields and this solution really helped me. I have updated the code for ECK fields for apply inline style in twig file like this:

<a style="color: {{ entity.field_link_color[0] }};" href="{{ entity.field_link[0]['#url'] }}"> {{ entity.field_link[0]['#title'] }} </a>

To get url:
{{ entity.field_link[0]['#url'] }}

To get link title:
{{ entity.field_link[0]['#title'] }}

Arti Prasad
  • 91
  • 1
  • 4
0

After rendering a block if you want to access the link field used in it then you can use like this $render['field_target_url']['#items']->uri inside node preprocess hook.

Debasish
  • 61
  • 1
  • 7
0

One more way is to add another field Path:Content if you are trying to fetch the URL in Views Fields

Jignesh Rawal
  • 521
  • 6
  • 17