Twig
Twig copied to clipboard
Trivial arrow filter
There are a few twig filters that allow arrow functions as argument: map, filter, reduce.
All of these apply the arrow function to array values (or keys).
I wonder, could we make a trivial filter that applies the arrow function to the original piped argument?
{{ set object = value|arrow(val => val ? {value: val} : {}) }}
The main purpose would be as part of a longer pipe chain.
I noticed this can already be done in userland, but it seems like a useful addition to core, or not?
new TwigFilter('arrow', [self::class, 'arrow'], ['needs_environment' => true]),
public static function arrow(Environment $env, $arg, $arrow) {
twig_check_arrow_in_sandbox($env, $arrow, 'arrow', 'filter');
return $arrow($arg);
}
Related:
- #3192 was rejected.
- #3402 was rejected.
I think the arrow() filter proposed here is quite basic and uncontroversial, is it not?
I don't think this filter belongs to the core. In most cases, the same result can be achieved by using a Twig expression directly.
I don't think this filter belongs to the core. In most cases, the same result can be achieved by using a Twig expression directly.
But then we can't chain it up with other filters easily. E.g. to have a macro inside a pipe.
{{ items
|filter(item => ..)
|map(item => ..)
|join(', ')
|arrow(markup => (markup|trim is not empty) ? _self.wrap('div'))
}}
Or to call a macro from apply:
{% set title %}
<h3>Hello</h3>
{% endset %}
{% apply arrow(markup => (markup|trim is not empty) ? title ~ markup : '') %}
{{ output }}
{% endapply %}
(btw the ~ operator loses the TwigMarkup class, but this is another story - see #3679)
To make this work this one line: https://github.com/twigphp/Twig/blob/3.x/src/ExpressionParser.php#L483 from:
foreach ($this->parseArguments() as $n) {
to:
foreach ($this->parseArguments(false, false, true) as $n) {
then closures all work in the context we want, e.g.:
{% set collection = collect(['a', 'b', 'c']) %}
{% set contains = collection.contains((value, key) => value == 'a') %}
with a nice, clean, normal syntax. I'd love to see this happen, too.
+1 for this.
As a consumer of Twig, I just want it to work as it looks like it should. And it looks like it should support closures. Why does it matter if there are other ways of doing it?
This is a solution for Craft CMS users: https://github.com/nystudio107/craft-closure
+1 from me on this too!
The change proposed by @khalwat seems clean!