8000 [DI] Some Twig extensions work automatically, others don't · Issue #22849 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[DI] Some Twig extensions work automatically, others don't #22849

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
javiereguiluz opened this issue May 22, 2017 · 19 comments · Fixed by twigphp/Twig-extensions#204
Closed

[DI] Some Twig extensions work automatically, others don't #22849

javiereguiluz opened this issue May 22, 2017 · 19 comments · Fixed by twigphp/Twig-extensions#204

Comments

@javiereguiluz
Copy link
Member
javiereguiluz commented May 22, 2017
Q A
Bug report? no
Feature request? no
BC Break report? no
Symfony version 3.3

In symfony/demo#562 we're updating the Symfony Demo app to 3.3.0 RC1 and all the new DI features. During the upgrade I saw this error:

Unknown "localizeddate" filter.

The reason is that I removed the original service definition for the Intl Twig extension:

app.twig.intl_extension:
    public: false
    class:  Twig_Extensions_Extension_Intl
    tags:
        - { name: twig.extension }

If I put the config back, everything works again. I think it's confusing that "auto-services" work for our own Twig extensions but not for Symfony's extensions. Is there anything we can do to improve this situation? Thanks

@stof
Copy link
Member
stof commented May 22, 2017

Well, what we could do is having TwigBundle registering this extension automatically when the twig-extensions package is installed (but keeping it an optional dependency of the bundle). I think this would fit the Flex idea of activating things by default when the package is installed.
What do you think @symfony/deciders ?

@xabbuh xabbuh added this to the 3.3 milestone May 22, 2017
@weaverryan
Copy link
Member

I think it's confusing that "auto-services" work for our own Twig extensions but not for Symfony's extensions

The explanation we need to "push" (and is accurate) is that we're auto-registering & tagging things in src/AppBundle only.

Well, what we could do is having TwigBundle registering this extension automatically when the twig-extensions package is installed (but keeping it an optional dependency of the bundle).

I like this! But, wouldn't we need to register all the extensions in that library then? That could be wasteful. Could we - as an alternative in Flex - add service configuration for all of the Twig extensions when twig-extension is installed... but commented-out (so you would need to go then activate each one).

@nicolas-grekas
Copy link
Member

See twigphp/Twig-extensions#204

@nicolas-grekas
Copy link
Member

Should we move this issue to the 3.4 milestone?

@weaverryan weaverryan modified the milestones: 3.4, 3.3 May 23, 2017
@weaverryan
Copy link
Member

I just changed to 3.4 milestone. If we're going to do anything in this repo, it would be a new feature to auto-register the Twig extensions in TwigBundle... so a new feature I think

fabpot added a commit to twigphp/Twig-extensions that referenced this issue May 24, 2017
This PR was merged into the 1.5-dev branch.

Discussion
----------

Add namespaced aliases

This is a first step towards moving this lib to namespaces.
It should fix symfony/symfony#22849
If it works well, the same strategy could be applied to Twig.
I think adding runtime notices would make things more complex and is not needed.

Commits
-------

fe6f308 Add namespaced aliases
@fabpot
Copy link
Member
fabpot commented May 24, 2017

Twig extensions 1.5.0 (with the needed changes) is out now.

@fabpot
Copy link
Member
fabpot commented Sep 10, 2017

It works, but you need to explicitly enable the extension:

Twig\Extensions\IntlExtension: ~

@fabpot
Copy link
Member
fabpot commented Sep 10, 2017

Not sure if registering all extensions automatically is a good idea. Some filters/functions could collide with some created by the developer locally, and it adds some overhead. Moreover, Flex is really all about adding only what you need. What we could do is adding a recipe that adds a file for those configurations, all commented, to ease discovery. See symfony/recipes#173

@weaverryan
Copy link
Member

+1

So, no changes to core needed. Any Twig extensions that you create in your src/ dir are auto-registered and tagged of course. And thanks to symfony/recipes#173, if you install twig-extensions, it gives you the code you need to opt-in. I love it :)

@LaurentMarquet
Copy link

I came there with Google and it seems to me, that's the good place to post the following.
In a standalone bundle, I have added in its services.yml the following config code

services:
    twig.intl_extension:
        class: Twig_Extensions_Extension_Intl
        tags:
            - name: twig.extension

But I receive the following error

Unable to register extension "Twig_Extensions_Extension_Intl" as it is already registered.

As this configuration is already done in the services.yml file of the app using the bundle. I have the same message when using Twig\Extensions\IntlExtension: ~.

The only way is to keep only one declaration, but this will lead to an error if the Twig_Extensions_Extension_Intl is not defined in the app.

Furthermore, if I do the same with Twig_Extensions_Extension_Text using

services:
    twig.text_extension:
        class: Twig_Extensions_Extension_Text
        tags:
            - name: twig.extension

It works! Even if declared on both app + bundle.

@curry684
Copy link
Contributor
curry684 commented Jul 31, 2018

A standalone bundle should not declare services that it is not providing itself.

Your bundle should either degrade gracefully if the extension is not installed by the end user, or provide the services you use from them yourself (if needed by wrapping the originally provided extensions), or last resort depend hard on the TwigExtensions package and use a late-phase compiler pass to register the service only if the end user did not already do this on application level.

@LaurentMarquet
Copy link

I will need some time (to understand) how to implement the bundle to degrade gracefully, if the extension is not installed, as I am just using localizeddate, but thanks for your explanation!
Symfony provides a lot of features and concepts that are easy when you understand them, but not so easy when you don't ;-)

@LaurentMarquet
Copy link

In fact my misunderstanding came because in the app/Resources/config/services.yml we define the services we use and provide, while in a standalone bundle Resources/config/services.yml we only define the services we provide, except if I'm still wrong.

@stof
Copy link
Member
stof commented Aug 1, 2018

well, in project-level, you still provide some services (using them is not happening in this file). The difference is that you can also provide services for some third-party classes, if these classes don't have a bundle providing the service.
The issue happens when multiple places are trying to provide similar services (Twig does not like multiple registrations of an extension, as it might lead to weird behavior sometimes)

@LaurentMarquet
Copy link
LaurentMarquet commented Aug 5, 2019

1 year and 4 days later I'm facing another problem with Twig Extensions and by googling I came there again ;-)
In my dev server I have in config/packages/twig_extensions.yaml

services:
    _defaults:
        public: false
        autowire: true
        autoconfigure: true

    # Uncomment any lines below to activate that Twig extension
    #Twig\Extensions\ArrayExtension: ~
    Twig\Extensions\DateExtension: ~
    Twig\Extensions\IntlExtension: ~
    #Twig\Extensions\TextExtension: ~

where it works well. But on my production server, having the same file as it's in a Git repo, it can't find the truncate filter.
I've tried to remove the # in front of TextExtension on production and it worked... Do you have any idea why? And how I can solve it? If I remove it on dev server it throws an error

"Unable to register extension "Twig_Extensions_Extension_Text" as it is already registered."

@xabbuh
Copy link
Member
xabbuh commented Aug 5, 2019

Do you have some bundle that is registered only in the dev environment that also comes with this extension?

@LaurentMarquet
Copy link

Great! You should be right! I'll investigate it as I have the following in my require-dev section

        "c975l/countlinescode-bundle": "^1",
        "c975l/xliff-bundle": "^2",
        "phpstan/phpstan": "^0",
        "rector/rector": "^0",
        "symfony/debug-pack": "*",
        "symfony/maker-bundle": "^1",
        "symfony/phpunit-bridge": "^4",
        "symfony/profiler-pack": "*",
        "symfony/test-pack": "*",
        "symfony/web-server-bundle": "^4",
        "symplify/easy-coding-standard": "^5"

Is there a way, instead of looking in each composer.json, to know which bundle requires what?

@xabbuh
Copy link
Member
xabbuh commented Aug 5, 2019

@LaurentMarquet
Copy link

It's one of the bundle I've developed ;-)
I've simply added a twig_extensions.yaml in config > packages > prod!
Thanks for your help!

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

Successfully merging a pull request may close this issue.

8 participants
0