Problem/Motivation

  • @Plugin is a dumping ground for metadata, and is often used for configuration, not metadata (information that is only useful once you have an instantiated plugin)
  • It also conveys no information to those looking at a plugin implementation
  • It provides no place to document the keys used by that particular annotation
  • Improved DX because we're putting an emphasises on the domain instead of the "system". I don't need to know that Entity types are plugins, I just need to know what metadata I need to provide for my EntityType.
  • Opportunity for custom validation/mapping in the constructor of the custom annotation class. I'd assume this is possible somehow with Plugins already, but doing it in the annotation class that you own is very intuitive and simple.

Proposed resolution

Introduce @PluginID for those that only need a plugin ID (Views handlers, Tour tips, eventually many basic ones in contrib)
Force any complex annotations to be custom classes, so they can be properly documented and discoverable.
For example, instead of @Plugin, have @EntityType.

@Plugin can be left in core for contrib, and might be extended by core annotations, but should not be used at all in core once this is done

Remaining tasks

Open issues for each plugin type

User interface changes

N/A

API changes

None yet

Namespace Class $owner $type Issue
Drupal\aggregator AggregatorPluginManager aggregator fetcher #1969692: Add a dedicated annotation for aggregator Plugins Assigned to: dawehner
Drupal\aggregator AggregatorPluginManager aggregator parser #1969692: Add a dedicated annotation for aggregator Plugins Assigned to: dawehner
Drupal\aggregator AggregatorPluginManager aggregator processor #1969692: Add a dedicated annotation for aggregator Plugins Assigned to: dawehner
Drupal\Core\Archiver ArchiverManager Archiver #2195585: Add a dedicated @Archiver annotation class
Drupal\block BlockManager Block #2065721: Add a dedicated @Block plugin annotation
Drupal\ckeditor CKEditorPluginManager CKEditorPlugin #1986988: Add a dedicated @CKEditorPlugin annotation Assigned to: tim.plunkett
Drupal\Core\Condition ConditionManager Condition #1990156: Add a dedicated @Condition plugin annotation
Drupal\Core\Constraint ConstraintManager Validation Constraint #2195083: Add a dedicated @Constraint annotation class
Drupal\edit EditorManager edit editor #1987140: Add a dedicated @InPlaceEditor plugin annotation Assigned to: damiankloip
Drupal\editor EditorManager editor editor #1992744: Add a dedicated @Editor plugin annotation Assigned to: quicksketch
Drupal\Entity EntityManager Core Entity #1967294: Add a dedicated @EntityType annotation
Drupal\entity_reference SelectionPluginManager entity_reference selection #2016589: Add a dedicated @EntityReferenceSelection annotation
Drupal\field FormatterPluginManager field formatter #1985344: Add a dedicated @FieldFormatter annotation
Drupal\field WidgetPluginManager field widget #2035315: Add a dedicated @FieldWidget annotation
Drupal\filter FilterPluginManager Filter #1868772: Convert filters to plugins
Drupal\layout LayoutManager Layout #2053879: Remove layout.module from core
Drupal\language LanguageNegotiationMethodManager language LanguageNegotiation #2195573: Add a dedicated @LanguageNegotiation annotation class
Drupal\rest ResourcePluginManager rest resource #2195571: Add a dedicated @RestResource annotation class
Drupal\system ImageToolkitManager ImageToolkit #1969708: Add a dedicated annotation for @ImageToolkit plugins
Drupal\tour TipPluginManager tour tip #1967406: Add a dedicated @Tip annotation Assigned to: tim.plunkett
Drupal\Core\TypedData TypedDataManager DataType #1867856: Use annotation discovery for data type plugins
Drupal\views ViewsPluginManager views $omg_so_many #1969388: Change notice: Add dedicated annotations for Views plugins
Drupal\views ViewsHandler views $omg_so_many #1965164: Add a @PluginID annotation for plugins that only need an ID, like Views handlers Assigned to: tim.plunkett
Drupal\plugin_test TestPluginManager plugin_test PluginTest #2200953: Add a dedicated @PluginTestFruit annotation class

Beta phase evaluation

Reference: https://www.drupal.org/core/beta-changes
Issue category Task because it is does not introduce new features or fix bugs.
Issue priority Normal because it replaces working code with better/consistent code.
Prioritized changes Prioritized because the change improves developer experience and adds self-documentation for creating new plugins of a particular type.
Disruption Minimally disruptive to contrib, since updating annotation types is trivial.

Comments

msonnabaum’s picture

Totally agree with the current summary.

Additional benefits:

- Improved DX because we're putting an emphasises on the domain instead of the "system". I don't need to know that Entity types are plugins, I just need to know what metadata I need to provide for my EntityType.

- Opportunity for custom validation/mapping in the constructor of the custom annotation class. I'd assume this is possible somehow with Plugins already, but doing it in the annotation class that you own is very intuitive and simple.

xjm’s picture

quicksketch’s picture

Introduce @PluginID for those that only need a plugin ID

Perhaps we should introduce both @PluginID and @PluginLabel, which provides a human-readable name. Hopefully this would allow removal of pseudo-function @Translate() in our annotations.

/**
 * Provides a 'System Help' block.
 *
 * @Plugin(
 *   id = "system_help_block",
 *   admin_label = @Translation("System Help"),
 *   module = "system"
 * )
 */

We would have something like:

/**
 * Provides a 'System Help' block.
 *
 * @PluginID system_help_block
 * @PluginLabel System Help
 */

Note I removed module entirely from this definition, since AFAIK, we can auto-determine this information anyway and it doesn't need to be defined in the annotation at all.

If we know that @PluginLabel is always translated, there's no need to wrap @Translate() around every single instance, any more than we wrap t() around menu titles and descriptions.

tim.plunkett’s picture

It will be @PluginID("system_help_block"), the parentheses and quotes are required.

I haven't looked into stacking multiple annotations yet, I will.

After a talk with EclispeGC, I changed our goal from removing @Plugin outright, to just not using it anywhere. It will be much easier to get started for contrib if they have @Plugin to use.

msonnabaum’s picture

I dont know if we need another annotation for that. Each Annotation class should know which keys need to be translated, so it can just do that in its constructor. I dont see a reason to keep @Translate around.

eclipsegc’s picture

well, I guess if we never want any strings in a plugin to be simply identified as translateable sure. I think there's still this fundamental ideal that we should be limiting plugin definitions in some way, and I don't really feel that's realistic. Having spoken with tim on this topic today at length, I'm not really opposed to a lot of these changes for the sake of organizing things further, but the Plugin class is so permissive because info hooks are, and it's replacing that. I don't know of any info hooks that we actively prevent alteration on and since plugins strive to be even more generic than most info hooks of the past, I'd prefer we not presume too much about a plugin's use case and prevent others from using it.

That being said there are probably use cases where we can get away with it (various views plugins for example), but this is extending the system in order to limit it, and I just don't want to see that become our default process or remove the more permissive system in favor of this one. Which brings me back around to Translate. Removing that class doesn't buy us anything, and in fact loses us quite a bit since now providing translateable strings (like description?) becomes something the developer has to deal with.

There're a lot of good ideas about very focussed use cases, and that's ok, but I'd prefer the generic use case classes not be targeted for any sort of removal. They're there for a good reason. If we want to expand the annotations we support with some focussed goal in mind, I'm ++ to that.

Eclipse

eclipsegc’s picture

Issue summary: View changes

Adjusted goals

tim.plunkett’s picture

tim.plunkett’s picture

Issue summary: View changes

Updated issue summary.

tim.plunkett’s picture

Issue summary: View changes

added table for sub-issues

tim.plunkett’s picture

Issue summary: View changes

add table formatting

tim.plunkett’s picture

Issue summary: View changes

Updated issue summary.

tim.plunkett’s picture

tim.plunkett’s picture

Issue tags: +Plugin system

Tagging.

tim.plunkett’s picture

Issue summary: View changes

Updated issue summary.

tim.plunkett’s picture

Issue summary: View changes

Updated issue summary.

tim.plunkett’s picture

Issue tags: +Annotation

Tagging

tim.plunkett’s picture

Issue summary: View changes

Updated issue summary.

tim.plunkett’s picture

Issue summary: View changes

Updated issue summary.

dawehner’s picture

Issue summary: View changes

added an issue for views plugins

dawehner’s picture

Issue summary: View changes

added issue for aggregator module

ParisLiakos’s picture

Issue summary: View changes

Fix aggregator issue links

dawehner’s picture

Linking an issue how to document @Translation need: #1969970: How to document needed @Translation on dedicated annotation classes

dawehner’s picture

Issue summary: View changes

added imagetoolkit plugin annotation

David_Rothstein’s picture

Improved DX because we're putting an emphasises on the domain instead of the "system". I don't need to know that Entity types are plugins, I just need to know what metadata I need to provide for my EntityType.

1. I'm not sure it accomplishes that since the code you will write for it still lives under a directory named "Plugin".
2. Is this even a good idea? When people are implementing hooks we don't try to hide that it's a hook. Why should plugins be different?

Otherwise, this proposal makes a lot of sense to me. To address the above, I'd just suggest that "plugin" be somewhere in the class name, and that the class name be as predictable as possible based in the name of the plugin that uses it. So for example @EntityPlugin rather than @EntityType.

@Plugin is a dumping ground for metadata, and is often used for configuration, not metadata (information that is only useful once you have an instantiated plugin)

I am not sure how in-scope that is for this issue (or how this issue would fix it) but I have gotten that impression as well, that plugin annotations are being overused right now (though never looked into it carefully enough to prove it). Conceptually, annotations are very similar to module .info files, so for typical plugins I don't see why annotations would need to contain much more than the kinds of basic information found in .info files. If this issue can fix that somehow, I'm all for it.

Which brings me back around to Translate. Removing that class doesn't buy us anything, and in fact loses us quite a bit since now providing translateable strings (like description?) becomes something the developer has to deal with.

Someone has to deal with it either way, right? I would prefer it be the person defining the plugin type than the person implementing the plugin.

Also, aren't a lot of translatable strings in plugins throughout core using a common set of keys (like "label", "description", etc)? If so, couldn't the base Plugin annotation class provide a method which translates those? Then the plugin type author would only have to override it (and call t() themselves) in the rare case where their annotations are using translatable strings with other keys.

I think it would be great if @Translation could go away - one less syntax for module develpers to have think about...

tim.plunkett’s picture

I have not brought it up in any issue yet because I don't want to have this fight quite yet, but the code I got in to support the move to custom Annotations can also help us alter the path based on plugin type.

For 98% of plugin types, we either want to be told its a plugin, or wouldn't be confused by that.

Entity types are different. We can now move \Plugin\Core\Entity to just \EntityType, like \Drupal\node\EntityType\Node, or \Drupal\taxonomy\EntityType\Vocabulary.

That's for another issue, I don't even want to hear pros and cons of that now.

@Translation isn't on the chopping block anymore right now, because localize.drupal.org will need it, or some other identifier, instead of t() when parsing files to find translatable string.

If we want to shift the burden off of implementors and onto l.d.o, that's a conversation you should have with Gabor :)

tim.plunkett’s picture

Issue summary: View changes

Added magical @ sign

tim.plunkett’s picture

Issue summary: View changes

Updated issue summary.

damiankloip’s picture

Issue summary: View changes

Added CKEditorPluginManager issue #

quicksketch’s picture

@tim.plunkett introduced an interesting pattern in #1986988: Add a dedicated @CKEditorPlugin annotation that could be applied to all plugins. Essentially it combines the $owner and $type variables from the table above into a single $owner$type namespace (or just $type in the case that $owner and $type are the same). i.e. block/block could become Block and ckeditor/plugin could become CKEditorPlugin. This results in less directory nesting and shorter namespaces, but at the cost of clarity and hardline namespacing.

Bike-shed discussion commencing at #1987298: Shorten directory structure and PSR-0 namespacing for plugins

quicksketch’s picture

Issue summary: View changes

Added edit editor plugin annotation issue.

tim.plunkett’s picture

Issue summary: View changes

Updated issue summary.

tim.plunkett’s picture

Issue summary: View changes

Updated issue summary.

damiankloip’s picture

Issue summary: View changes

Added condition conversion issue

quicksketch’s picture

Issue summary: View changes

Adding Editor module.

tim.plunkett’s picture

Issue summary: View changes

Adjusted $owner/$type

jhodgdon’s picture

I just edited the issue summary to add a link to this related sub-issue:
#1970900: Update standards doc on plugin annotations; add @defgroup annotation

jhodgdon’s picture

Issue summary: View changes

Add link to issue 1970900

tim.plunkett’s picture

Issue summary: View changes

Updated issue summary.

tim.plunkett’s picture

Issue summary: View changes

Updated issue summary.

tim.plunkett’s picture

Issue summary: View changes

TypedData

catch’s picture

Status: Active » Fixed

Looks like this is all done now? Please re-open and stick the remaining issues in the summary if not.

catch’s picture

Issue summary: View changes

Updated issue summary.

amateescu’s picture

Status: Fixed » Active

Not yet :( I updated the summary with the issue for FieldWidget and the one where layout.module was removed, but we still have ArchiverManager, ConstraintManager and ResourcePluginManager.

joachim’s picture

> It provides no place to document the keys used by that particular annotation

Annotation classes only go some of the way.

If you look at https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Entity!Annotation..., compared to https://api.drupal.org/api/drupal/modules!system!system.api.php/function... --

- we've lost the general intro to the concept
- we've lost readability. The list of class properties is much harder to read down that the properties docblock we had for the hook
- we've lost sample code.
- that means we've also lost the sample values for each property that are given in the sample code

Furthermore, there are new concepts in the plugin system that developers need to know about but which aren't represented here:

- what's the subdirectory to use for the plugin?
- what's the name of the service to get the plugin manager?

These are all things that need to be better joined up in the docs so that developers can actually make sense of how it fits together.

If the issue here is improving DX for working with plugins, then we need to think of the bigger picture.

Edit: bigger picture #2086397: Find a consistent way to document plugin types.

joachim’s picture

Issue summary: View changes

Added the issue where FieldWidget was introduced and where layout.module was removed from core.

les lim’s picture

Issue summary: View changes
les lim’s picture

Issue summary: View changes
les lim’s picture

Issue summary: View changes
les lim’s picture

Issue summary: View changes
les lim’s picture

Issue summary: View changes
mgifford’s picture

mgifford’s picture

mgifford’s picture

les lim’s picture

Issue summary: View changes

Added beta evaluation.

xjm’s picture

Coming here from #2195573-21: Add a dedicated @LanguageNegotiation annotation class. "Improving developer experience" by itself doesn't make the change acceptable during the beta. However, the point of this issue is also to make it possible to document the keys for each annotation, which is prioritized for sure. Finally, there are only a handful of these that did not get done pre-beta. So I'm inclined to grant an exception and consider these as prioritized changes.

As far as I can see, there are only three child issues remaining:

  1. #2195573: Add a dedicated @LanguageNegotiation annotation class was RTBC; I just postponed it, hopefully briefly, on a discussion here. The disruption from that is probably merited by the valuable impact of the patch, since I don't think there are too many implementations of that about.
  2. #2200953: Add a dedicated @PluginTestFruit annotation class should only be test code, so unfrozen anyway.
  3. #2195083: Add a dedicated @Constraint annotation class I'm more concerned about the potential disruption, since I think this plugin type is used a lot in things like Rules, Panels-ish stuff, etc. I'll ping a couple maintainers and ask for feedback on whether that change would make their lives easier or harder. (I'm hoping easier since @fago was working on the patch at least.)
tim.plunkett’s picture

2) I need to reread it, but I think the PluginTestFruit was our non-custom annotation test coverage, so I think we might want to keep that?
3) You'll have to check with Rules, but it doesn't affect panels/page_manager at all.

eclipsegc’s picture

Yeah, it'd be really great to get all of these. It'd give us the option of making the Plugin annotation abstract, which I think is probably favorable before 8.0.0 release (since it would heavily re-enforce this same paradigm in contrib, which I think we all want. Care to comment on that Tim?

Eclipse

xjm’s picture

From @berdir in IRC:

I would have to update a few custom validation plugins, but that's fine. The biggest conceptual API change would be to make the Plugin annotation class abstract as suggested by EclipseGc, not sure if that's a good idea (I'm not aware of any contrib module using that, so it would likely not have an real-life consequences)

eclipsegc’s picture

We're enforcing an optional core standard on contrib if we make Plugin Annotation abstract. I think that's a good idea, but it's not something to sweat horribly at this point. Really either way. We either value everyone adopting this standard or we don't. For the moment, I think there's sufficient examples within core that people are likely to follow the standard anyway, it's just a matter of forcing it or not. Not like they couldn't extend Plugin and then keep doing what it does today, so we really have no authority at all :-D

Eclipse

TL:DR; I think it's a good idea, but it doesn't really matter so, it probably doesn't factor into the decision.

les lim’s picture

There's already a follow-up issue for making Plugin abstract at #2195557: Make Drupal\Component\Annotation\Plugin abstract. That issue should really have a separate beta evaluation -- it's not required for this issue and doesn't present any reasons to block it.

eclipsegc’s picture

Correct, I'm saying quite the opposite. This issue is a requirement of that issue... not vice versa. If we don't provide a custom annotation for each plugin type, we cannot ever make Plugin abstract. That's all I'm saying.

Eclipse

xjm’s picture

Agreed, for this issue, we should only be discussing the issues in #28, so that we can unpostpone them if appropriate.

@alexpott and @fago haven't commented yet. @alexpott said in IRC:

I think I'm +1 because we've very nearly achieved what they set out to do in april 2013

fago’s picture

yeah, I'm fine with the Constraint annotation class being added. It does not touch Rules at all so far.

Instead I think it's more related to people that need to customize their entity validation and are providing custom constraints for that - as berdir mentioned in #31. If we really want to take care of them, we could still support @Plugin for those also maybe? But +1 on generally fixing this, it would be weird to have only constraint plugins use @Plugin.

xjm’s picture

Alright, thanks everyone. Based on #36 and above I'm going to unpostpone those two child issues for @Constraint and @LanguageNegotiation.

les lim’s picture

Proposed change record here: https://www.drupal.org/node/2484461

eojthebrave’s picture

I reviewed the change record. And it looks good. Thanks Les. Though I suppose we should probably wait to publish it until the @Constraint and @LanguageNegotiation issues are fixed.

eric_a’s picture

Is this meta open for #2200953: Add a dedicated @PluginTestFruit annotation class only? Is it worth holding up publishing a change record for?

les lim’s picture

Category: Task » Plan

I've updated that last issue to suggest that we keep it using @Plugin, since we technically still allow contrib to do that. If so, we can publish the change record and close out the whole meta.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

andypost’s picture

Issue tags: -

I think cr could be published and issue closed as there's only one child issue left

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

quietone’s picture

Status: Active » Fixed

There is one issue left here to complete and I have changed the parent of that issue to #3396165: [meta] Convert all core plugin types to attribute discovery. I have updated the CR here to list the plugin types changed that did not have a separate change record. This CR is now published with the date adjusted to 2015.

Therefor, I am closing this issue as fixed.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.