Getting Value (URI) of a Drupal Media (File) Field from within a Twig Template

To the future or to the past, to a time when thought is free, to the next time when I need to get the value of file field to use as a variable in Drupal 8 with Twig.

Working my way down through one of Drupal's render arrays of doom to try to get the URI of a file in a media field (in a paragraph type), I came up with this. If you can improve it, feel free to drop a note in the comments:

{% set slide_url = file_url(content.field_p_ei_speaker_slides[0]['#media'].field_m_file_file.entity.uri.value) %}

In steps:

  1. Get the {{ content }} variable
  2. Drill down into the media field (Speaker Slides - pdf, ppt, etc)
  3. Get the first element (0 - it's not a multi-value field in this case)
  4. Load up the #media object
  5. Interrogate the field on the media entity that has the file attached (the File field)
  6. Load this entity (entity here is not presented as an item in the {{ dpm() }} but it's very handy to know
  7. Get the uri.value from here
  8. Wrap it all in a file_url() function

For clarity, here's what I had in PatternLab:

  {# Begin Slides Download #}
  {% if event_slide_download %}
    <div class="event-item__slides">
      <a href="{{ event_slide_download_link }}">
        {% include '@basic-elements/icons/_svg.twig'
          with {
            svgpath : '@basic-elements/icons/svg/download.svg'
  {% endif %}
  {# End Slides Download #}

And here's what I have in the corresponding Drupal paragraph.html.twig tempate:

{% if paragraph.field_p_ei_speaker_slides.value %}
  {% set event_slide_download = true %}
  {% set slide_url = file_url(content.field_p_ei_speaker_slides[0]['#media'].field_m_file_file.entity.uri.value) %}
  {% set event_slide_download_link = slide_url %}
{% endif %}

{% include "@building-blocks/event-section/event-item.twig" %}

So now, my future self, you will know where to find this next time.

For posterity, here's a blog by Norman Kamper on how to create a custom field formatter, written as a response to this post, and the code is available on github. Thanks Norman.

Filed Under:

  1. Drupal
  2. Twig
  3. Frontend Development
  4. Drupal Planet