Working with HTML Classes
I like this approach as it keeps it easy to read, and git diffs are easier to understand as well. I think that the concept of including something and setting a value like isDark
to true and getting a BEM Modifier class added works really well.
{% set classes = [
'card',
media ? 'card--has-media',
isDark ? 'card--is-dark',
] %}
<div class="{{ classes|join(' ') }}"></div>
If you want to take it even further, you can enable the file that is including the above template to add some classes. So our first template, let's call it a.twig
, would look like this instead:
{% set classes = [
'card',
media ? 'card--has-media',
isDark ? 'card--is-dark',
] | merge(classes|default([])) %}
<div class="{{ classes|join(' ') }}">
What's that default([])
all about?
Well, I'm trying to merge classes
with classes
if it's already there, and if it isn't, then using merge
will yell at me as I'm trying to merge an array with null
so I tell it to merge it with []
if classes
is not present. So basically the default of classes
if it's not present, is []
.
And our second template could add some classes to that like so:
{% include 'a.twig' with {
isDark: true,
classes: ['my-extra-class'],
}
%}
This would result in this HTML:
<div class="card card--is-dark my-extra-class"></div>
About that extra space...
If you spotted the extra space in the class list, good catch – that comes from the fact thatmedia
was false and therefore returned null
- however it took up a spot in our array which was join
ed with a space to make the list. I'll often pass the end string through | trim
to get rid of the ones at the beginning and end, but it's not that big of a deal and is totally valid, functional markup.
Drupal 8 & Twig
Accessing Data
If you want to access fields and their values, start off with node
, not content
, which is a render array with the configured fields.
If you want a field's value, most of the time you simply append .value
: node.field_name.value
.
When trying to figure out what's in a content entity, use node.toArray()
, that gives you an array representation that's very close to how you can access it as an object. While the internal structure is quite different.
Entities References
If it's an entity reference, you can dive into it via .entity
.
To access the label of a term reference for example, you can access it as block_content.field_tags.entity.name.value
.
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
.