Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Use classes for container tags #37194

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
Tobion opened this issue Jun 10, 2020 · 7 comments
Closed

Use classes for container tags #37194

Tobion opened this issue Jun 10, 2020 · 7 comments

Comments

@Tobion
Copy link
Contributor

Tobion commented Jun 10, 2020

Currently tags are just strings and the attributes are arrays whose values depend on the tag. See for example

->set('data_collector.twig', TwigDataCollector::class)
->args([service('twig.profile'), service('twig')])
->tag('data_collector', ['template' => '@WebProfiler/Collector/twig.html.twig', 'id' => 'twig', 'priority' => 257])

I propose to allow define tags as classes which just need to implement an interface like

interface ContainerTagInterface
{
    public function getName(): string;
    public function getAttributes(): array;
}

Then we can allow tags to be instances of the interface and can create classes that represent the tags , e.g. ->tag((new DataCollectorTag)->template('...')->id('twig')->priority(257)). This makes tags discovorable, autocomplete, supporting types, documentable in code and validatable.

The main objective with the move to use PHP to define services (#36778) is discovorability and auto-completion. With tags as classes this would also improve the situation for tags as people can easiliy find the available tags as the classes implement this interface and the attributes for each tag allow auto-completion.
Before using php for service definitions, tags as classes wasn't really an option in YAML/XML. But now I think it's time to do that transition for the php configuration format. This is also more in-line with similar concepts like the Messenger stamps that are classes as well.

A previous proposal to use constants for tags (#24377) did not solve the problem for attributes and also does not improve discovorability much as it highly depends on where you define the constants.

@stof
Copy link
Member

stof commented Jun 10, 2020

I see a big drawback to your proposal: currently, it is perfectly fine to define services that hook into extensions points of other bundles (through a tag), without checking first whether the bundle is enabled (which is a pain if you care about it being enabled, and not just installed, even without counting the extra pain when using non-PHP files). That works fine, as Symfony will remove this private service which is unused when the bundle is not there.

But if you use a tag builder object from the bundle itself, your config file now has a strong dependency to that bundle.

And I also fear that it might push bundles to implement some logic in their MyTag::getAttributes logic instead of doing it in compiler passes, making the smart logic unusable for people using XML or Yaml. AFAIK, there is no plan to remove support for XML and Yaml configuration formats.

@jkufner
Copy link

jkufner commented Jun 15, 2020

Having the getAttributes() method kind of degrades the use of a class here. Such a tag class should have only the name and then the particular tag implementations should add custom getters for the attributes.

I like the idea; however, it introduces some serious problems. The absence of strict checking is quite useful here as it allows us to specify metadata that may or may not be used (as @stof explained), or to add custom metadata to existing tags that are used by a custom compiler pass. On the other hand, if we can deal with these usecases, then it would be a great improvement.

@Tobion
Copy link
Contributor Author

Tobion commented Jun 16, 2020

Having the getAttributes() method kind of degrades the use of a class here. Such a tag class should have only the name and then the particular tag implementations should add custom getters for the attributes.

getAttributes is only called internally when adding the tag. what would custom getters do? this is only about the external way to add tags. internally, e.g. in compiler passes, things would stay the same. otherwise we would need to deprecate using strings/arrays as name/attribute completely. that would be an extra step that is probably not worth it.

or to add custom metadata to existing tags that are used by a custom compiler pass

just use a separate tag for this

@nicolas-grekas
Copy link
Member

nicolas-grekas commented Aug 31, 2020

@stof has a point. Declarative statements don't play very well with classes which all need implementations (the same will be true with php8's attributes btw.)

@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

Friendly ping? Should this still be open? I will close if I don't hear anything.

@nicolas-grekas
Copy link
Member

#39804 and #39897 should be good substitutes for this. Closing therefor.

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

No branches or pull requests

5 participants