Skip to content

[Twig-Bridge] [RFC] Allow to declare twig extensions via config ? #53403

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

Closed
VincentLanglet opened this issue Jan 4, 2024 · 6 comments
Closed
Labels
RFC RFC = Request For Comments (proposals about features that you want to be discussed) Stalled TwigBridge TwigBundle

Comments

@VincentLanglet
Copy link
Contributor

VincentLanglet commented Jan 4, 2024

Description

Maybe I misunderstood some things about TwigRuntime but when I create one I have to do:

  • One runtime, with some services injections and a method doThings.
  • One twigExtension with the code:
new TwigFunction('doThings', [MyRuntime::class, 'doThings']),

This create duplicate classes.

Eventually, one thing I can do is to have multiple runtimes, but one single twigExtension calling all of them.

new TwigFunction('doThings', [MyRuntime::class, 'doThings']),
new TwigFunction('doOtherThings', [MyOtherRuntime::class, 'doOtherThings']),

But I was wondering the purpose of this twigExtension in such case and if this couldn't be generated by some config directly:

framework:
    twig:
        functions:
        filters:
        tests:

What do you think about such feature ?

@carsonbot carsonbot added the RFC RFC = Request For Comments (proposals about features that you want to be discussed) label Jan 4, 2024
@stof
Copy link
Member

stof commented Jan 4, 2024

See twigphp/Twig#3916 where this is in progress (we will need a configuration layer in TwigBundle leveraging this new code, once the foundation is merged in Twig)

@stof
Copy link
Member

stof commented Jan 4, 2024

Actually, the TwigBundle PR already exist at #52748

@94noni
Copy link
Contributor

94noni commented Jan 5, 2024

It would indeed simplify twig custom registration logic (perhaps not usefull when attributes are in place)

At work we do have an internal sort of such thing:

# service.yaml
FrontBundle\Component\CMS\Twig\ConfigurableExtension:
        $globals: []
        $filters:
            app_format_price: ['@CoreBundle\Twig\Runtime\MoneyFormatterRuntime', 'formatPrice']
            app_format_html_price:
                callable: ['@CoreBundle\Twig\Runtime\MoneyFormatterRuntime', 'htmlPrice']
                options:
                    is_safe: ['html']
        $functions:
            app_get_product: ['@FrontBundle\Twig\Runtime\ProductHelperRuntime', 'getProduct']
            app_image_url_for_path: ['@CoreBundle\Twig\Runtime\ImageProviderRuntime', 'getImageUrlForPath']
            app_render_offer_discount:
                callable: ['@CoreBundle\Twig\Runtime\UtilsRuntime', 'renderDiscount']
                options:
                    needs_environment: true

with class as service extending the twig abstract extension

Code

<?php

declare(strict_types=1);

namespace FrontBundle\Component\CMS\Twig;

use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Twig\TwigFunction;

class ConfigurableExtension extends AbstractExtension
{
    /**
     * @var string[]
     */
    private $globals;

    /**
     * @var callable[]
     */
    private $filters;

    /**
     * @var callable[]
     */
    private $functions;

    public function __construct(array $globals, iterable $filters, iterable $functions)
    {
        $this->globals = $globals;
        $this->filters = $filters;
        $this->functions = $functions;
    }

    public function getGlobals()
    {
        return $this->globals;
    }

    public function getFilters(): array
    {
        $arr = [];
        foreach ($this->filters as $name => $callable) {
            if (isset($callable['callable'])) {
                $arr[] = new TwigFilter($name, $callable['callable'], $callable['options'] ?? []);
            } else {
                $arr[] = new TwigFilter($name, $callable);
            }
        }

        return $arr;
    }

    public function getFunctions(): array
    {
        $arr = [];
        foreach ($this->functions as $name => $callable) {
            if (isset($callable['callable'])) {
                $arr[] = new TwigFunction($name, $callable['callable'], $callable['options'] ?? []);
            } else {
                $arr[] = new TwigFunction($name, $callable);
            }
        }

        return $arr;
    }
}

@carsonbot
Copy link

Thank you for this suggestion.
There has not been a lot of activity here for a while. Would you still like to see this feature?

@carsonbot
Copy link

Hello? This issue is about to be closed if nobody replies.

@carsonbot
Copy link

Hey,

I didn't hear anything so I'm going to close it. Feel free to comment if this is still relevant, I can always reopen!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RFC RFC = Request For Comments (proposals about features that you want to be discussed) Stalled TwigBridge TwigBundle
Projects
None yet
Development

No branches or pull requests

5 participants