3

From a field template level, how can I get the link field URL value so I can theme this thing? Here is my overridden field template for this field:

{% for item in items %}
    {%
      set classes = [
        'btn',
        (loop.index0 == 0) ? 'btn--primary' : 'btn--inverted'
      ]
    %}

    <a href="{{ item.content['#uri'] }}" class="{{ classes|join(' ') }}">{{ item.content['#title'] }}</a>
{% endfor %}

It only holds two possible values.

I have tried every possible way to access the field value, but nothing seems to work.

  • It's bad practice to create the anchor tag like above. – Eyal Nov 17 '16 at 0:09
  • You should create a link render array in preprocess and revert it instead. – Eyal Nov 17 '16 at 0:10
  • Revert? You mean render? – Kevin Nov 17 '16 at 0:15
  • Yes, I meant render (autocorrect). – Eyal Nov 17 '16 at 0:16
2

If you want to do the theming of the link field from a field twig level, it might be a better approach to keep the existing link render element, which is in item.content and add the bootstrap classes to it:

field--link.html.twig

{#
/**
 * @file
 * Theme override for a field.
 *
 * Add bootstrap button style to a link field
 */
#}
{% for item in items %}
  {%
    set link_classes = [
      'btn',
      (loop.index0 == 0) ? 'btn--primary' : 'btn--inverted'
    ]
  %}
  {% set content = item.content %}
  {% set content = content|merge({ '#attributes': { class: link_classes } }) %}
  {{ content }}
{% endfor %}

You have to get item.content on the top level of the array, so that you can merge #attibutes. That is why you need {% set content = item.content %}.

| improve this answer | |
  • Interesting - where in the docs did you see this – Kevin Nov 17 '16 at 14:18
  • That's my code. – 4k4 Nov 17 '16 at 14:24
  • Ok, so you can merge them into the render array at this point. That works. I assume you can add other attributes here if you wanted to as well, other than class? – Kevin Nov 17 '16 at 14:31
  • Yes, that's the same as in preprocess. If the variable contains a render array you can change it. The problem is, that twig has not very much tools to manipulate arrays, so for more complex things you better use php. – 4k4 Nov 17 '16 at 14:35
1

Ok... found my answer.

There are two ways you could do this. One way, is in the themename.theme file:

function mytheme_preprocess_field(&$variables) {
  if ($variables['element']['#bundle'] == 'motivation_card' && $variables['element']['#field_name'] == 'field_link') {
    foreach ($variables['items'] as $index => $item) {
      $variables['items'][$index]['content']['url'] = $item['content']['#url']->toString();
    }
  }
}

Another (preferable) way that I used is to use the render_var twig function.

{{ render_var(item.content['#url']) }}
| improve this answer | |
  • I don't think you need the render_var function call. Try {{ item.content['#url'] }} – Eyal Nov 17 '16 at 0:03
  • That didn't do anything without the render_var. – Kevin Nov 17 '16 at 0:15

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.