Problem/Motivation
To convert variants machine names to HTML class, we use 2 code snippets in the pattern templates.
The simple one:
{% if variant != '' and variant|lower != 'default' %}
{% set attributes = attributes.addClass('list-group-' ~ variant|lower|replace({'_': '-'})) %}
{% endif %}
A more complicated one when there are more than one classes to add:
{% if variant != '' and variant|lower != 'default' %}
{% set variants = variant|split('__') %}
{% for variant in variants %}
{% set attributes = attributes.addClass('badge-' ~ variant|lower|replace({'_': '-'})) %}
{% endfor %}
Sometimes it is a bit different, but those 2 snippets are common among patterns. And we find them in other UI Suite implementations.
Everything works well so far, but there are 2 little improvements possible:
- Sometimes the complicated one is used even when there is no "__" in the variant names. It is useless and confusing.
- The complicated one is setting a value inside a loop (attributes) which will be used outside the loop. Twig doesn't allow that. Variables defined inside a loop are scoped to that loop. It works in our templates only because the attributes variable was magically injected by Drupal before. Let's not rely on that.
Proposed resolution
Replace the complicate snippet by the simple one when it is enough.
For the assignment inside loop issue, 2 proposals:
1. Replace the loop by a map filter:
{% if variant and variant|lower != 'default' %}
{% set variants = variant|split('__')|map(v => v|lower|replace({(v): 'badge-' ~ v})|replace({'_': '-'})) %}
{% set attributes = attributes.addClass(variants) %}
{% endif %}
2. Or set the attribute object before the loop:
{{% set attributes = attributes|default(create_attribute()) %}
{% if variant != '' and variant|lower != 'default' %}
{% set variants = variant|split('__') %}
{% for variant in variants %}
{% set attributes = attributes.addClass('badge-' ~ variant|lower|replace({'_': '-'})) %}
{% endfor %}
The first one looks slicker and better, and this is the one we pick for other projects (UI Suite Bootstrap and UI Suite Material).