Skip to content

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

@MoritzLost

Description

@MoritzLost

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions