The `default` filter should only evaluate the expression passed to it if necessary
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 8.4k
- Forks
- 1.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 37
Description
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.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating the default filter implementation and the generated PHP for filter arguments. Check how existing Twig tests cover default with falsy and non-null values, then add a regression case showing that some_expensive_function() is skipped when the input is truthy and evaluated when the default is needed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100