Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trivial arrow filter #3677

Closed
donquixote opened this issue Apr 7, 2022 · 11 comments
Closed

Trivial arrow filter #3677

donquixote opened this issue Apr 7, 2022 · 11 comments

Comments

@donquixote
Copy link

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);
  }
@donquixote
Copy link
Author

donquixote commented Apr 7, 2022

Related:

I think the arrow() filter proposed here is quite basic and uncontroversial, is it not?

@stof
Copy link
Member

stof commented Apr 7, 2022

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.

@donquixote
Copy link
Author

donquixote commented Apr 7, 2022

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)

@khalwat
Copy link

khalwat commented Aug 2, 2022

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.

@MattWilcox
Copy link

MattWilcox commented Mar 22, 2023

+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?

@khalwat
Copy link

khalwat commented Mar 22, 2023

This is a solution for Craft CMS users: https://github.com/nystudio107/craft-closure

@thupsi
Copy link

thupsi commented Mar 22, 2023

+1 from me on this too!

The change proposed by @khalwat seems clean!

@fabpot
Copy link
Contributor

fabpot commented Oct 2, 2024

Here, the comments are talking about something different from the ticket description. The description talks about having an arrow function whereas the rest is about supporting arrow functions as arguments. Is that correct?

@khalwat
Copy link

khalwat commented Oct 2, 2024

@fabpot correct, the discussion is more directly related to the unfortunately Rejected issue here: #3192

@fabpot
Copy link
Contributor

fabpot commented Oct 4, 2024

Closing here and reopening #3192

@fabpot fabpot closed this as completed Oct 4, 2024
@donquixote
Copy link
Author

Hello @fabpot

Here, the comments are talking about something different from the ticket description. The description talks about having an arrow function whereas the rest is about supporting arrow functions as arguments. Is that correct?

Indeed the comments are somewhat off track, I don't really see how they relate to the original request.

For me, the original request is still valid, it would provide more possibilities in filters and pipe expressions, which would otherwise require cluttered code blocks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

6 participants