Twig default filter makes it hard to decline a default value

Created on 24 January 2025, about 1 month ago

Problem/Motivation

When the twig default filter is used to supply a default for an array, such as optional classes, the invoking template cannot decline the default value by passing an empty array. For example, in fieldset.twig, there is:

{% set fieldset_content_classes = fieldset_content_utility_classes|default(['mb-3']) %}

So if you want a fieldset without the mb-3 class applied to the content div, you cannot simply pass fieldset_content_classes: [] because the empty array is not considered a value by the default filter. Instead, you would have to apply a class you don't actually want just to suppress the default, such as ['some-nonexistant-class']. The same holds for the idiom using the ?: operation.

Proposed resolution

For places where a null value is what really represents the desire for a default, the null coalescing operator could/should be used instead. For example:

{% set fieldset_content_classes = fieldset_content_utility_classes ?? ['mb-3'] %}

Passing nothing or null gives the default mb-3.
Passing an empty array gives no additional classes and does not add mb-3.
Passing a non-empty array gives those classes and does not add mb-3.

I think this is exactly what someone would want.

This could be applied systematically to all templates, especially component templates.

API changes

It's unclear to me if this would be a backward-compatibility breaking change. I tend to think the risk is low.

✨ Feature request
Status

Active

Version

6.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States danchadwick Boston

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

Merge Requests

Comments & Activities

  • Issue created by @danchadwick
  • Hey Dan, this sounds about right to me, at some point, I slowly tried to convert them but seems like I never finished. That aside, I don't believe there would be any breaking change with this, so feel free to get this going.

    Thanks a lot

  • Pipeline finished with Success
    about 1 month ago
    Total: 136s
    #410328
  • I have perfrom the suggested changes to all component templates. Please review the MR.

  • πŸ‡ΊπŸ‡ΈUnited States danchadwick Boston

    @sandippoddar - Thank you for the MR. I think this is too aggressive. We need to distinguish two different types of situations regarding defaulted arguments.

    1. The template must have a value and if none is supplied, either by a null value or by another "falsey" value, such as an empty string or empty array, then the default should be supplied. This is where the default() filter is useful. The one tricky case is when the default is supplying a boolean, because the default filter will turn a boolean false value into true. Here the ?? operator is useful.

    2. The template wants a value where a falsey value is a perfectly valid default and a distinction must be made between no default (null) and a falsey default. The example I gave is supplying extra "utility" classes to be added to other classes in the template. Here the use of the ?? operator to supply the default only when no argument value is supplied (null) and not override a falsey default like the empty set [].

    Make sense?

  • Thanks for the feedback now it is clear to me i am working on it.

  • Pipeline finished with Success
    14 days ago
    Total: 139s
    #427273
  • Hi @danchadwick, I have done the changes can you please share your feedback on it.

Production build 0.71.5 2024