15

I have a list field for a custom block type that looks like this:

left|Align left
right|Align right

I can access the key in Twig by doing something like this:

{% block content %}
  {{ content.field_align }}  {# outputs 'right' #}
{% endblock %}

However, if I do a simple comparison, it outputs FALSE.

{{ kint(content.field_align == 'right') }}

The following code returns TRUE.

{{ kint(content.field_align['#items'].getValue()|first.value == 'right') }}

Is there a shorter version for getting the "real" string so I can use Twigs string filters and keep it tidy?

1

3 Answers 3

16

content contains the render arrays based on the configured formatters.

If you want to access the actual values, you want to access them through the entity object. Usually, that is available already to your template, for example node. For your case, it is a bit special because the block_content is rendered in the block content without its own template, so you have to make it available yourself in a yourtheme_preprocess_block($variables) like this:

if (isset($variables['elements']['content']['#block_content'])) {
  $variables['block_content'] = $variables['elements']['content']['#block_content'];
}

Then, you can access a field value with block_content.field_name.property. So in your case, block_content.field_align.value. The property is value for most field types, for references, you can either use target_id for the ID or entity for the referenced entity object. Yes, you can directly access fields on that, but make sure to always check that a reference exists otherwise you can end up with fatal errors or exceptions. To access the label of a term reference for example, you can access it as block_content.field_tags.entity.name.value.

If you don't specify the field delta, it defaults to the first. If you want to access a different delta, you can use entity.field_name.1.valueand so on. You can also loop over them.

This all maps directly to PHP, you can also do $block_content->field_tags->entity->name->value in preprocess and other places where you have the block_content.

3
  • Thanks for your answer! As I am doing this from the block twig template where the node object isn't available (sub-theming "Classy"), would I need to preprocess the values and inject them somehow?
    – estrar
    Aug 27, 2015 at 6:06
  • Sorry, I missed the block_content part. Updated the answer.
    – Berdir
    Aug 27, 2015 at 6:11
  • Perfect! I could get the values by doing this: block_content.field_name.value Thank you for helping me understand!
    – estrar
    Aug 27, 2015 at 6:52
6

Here's an alternative, template only way which allows you to render a render array and check its value (allows checking the variable as if you were printing it, because printing in Drupal 8 Twig automatically renders variables that are render arrays):

{{ kint(content.field_align|render == 'right') }}

Or another option to save the extra render if you're printing the variable later:

{% set field_align = content.field_align|render %}
{{ kint(field_align == 'right') }}

{{ field_align }}
1
  • Very useful and good to know! Thanks for the input.
    – estrar
    Aug 28, 2015 at 9:41
2

You can use Twig Field Value module in this case. It allows to get partial data from field render arrays. For ex. content.field_name|field_value -get value of field. You can use it in IF statement

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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