Twig icon indicating copy to clipboard operation
Twig copied to clipboard

The `default` filter should only evaluate the expression passed to it if necessary

Open MoritzLost opened this issue 5 months ago • 0 comments

Not sure if this is a bug or just unexpected behavior, but I just found that the expression passed to the default filter will always evaluate the expression that is passed to it, even when it's not required.

{% set foo = bar | default(some_expensive_function())%}

In this example, from a template developer's perspective, I would expect that some_expensive_function() is only called if bar is falsy. However, it's always called, no matter the value of bar.

This is a problem when the parameter is expensive to compute or requires a database call. For example, in Craft CMS template, I often do something like this:

{% set image = image | default(entry.image.one()) %}

This will either take the image passed to the template, or load a fallback image from the database. I only want to run the additional database query when image is empty.

I can use null coalescing, which behaves differently. But sometimes I want the default filter, to also handle cases where the first variable may be falsy, but not null.

I don't know how complicated this change would be. At least in theory, I don't see any reason why the default filter couldn't use short-circuiting in its generated PHP code to avoid running the expression unnecessarily.

MoritzLost avatar Jul 22 '25 20:07 MoritzLost