twigphp / twigphp/Twig

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

Open
#4,668 2 comments 3 reactions 0 assignees View on GitHub

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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.