Better variants to HTML class conversions

Created on 14 March 2023, almost 2 years ago
Updated 27 March 2023, over 1 year ago

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 aptterns. And we find them in other UI Suite implementations.

Everything works well so far, but there are 2 little stuff we can do to make it even better:

  • Sometimes the complicated one is used even when there is no "__" in the variant names. It is useless and confusing. Example in BS4: alert.
  • 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.

Remaining tasks

For 4.x, push directly the commit. For 5.x, do a MR.

📌 Task
Status

Fixed

Version

5.0

Component

Code

Created by

🇫🇷France pdureau Paris

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024