The Drupal 8 Plugin system is largely in a state that it could be committed to core: #1497366: Introduce Plugin System to Core however, there are some concerns that the plugin system may not be particularly obvious from a DX use case. Those of use who have developed the plugin system thus far feel quite the opposite, and so we have tried to put together a simple use case to demonstrate the use of plugins. We need some people who are willing to dig in here a bit and give some serious feedback. This issue is the second of two.
Within this issue we want feedback on building plugin types. Core, contrib, etc usecases welcome. Any work done here should be reusable for either D8 itself or hopefully contrib modules you maintain and intend on upgrading.
Documentation on this process largely already exists here : http://drupal.org/node/1637614
The current D8 + plugins branch can be found here:
git clone --recursive --branch plugins-next http://git.drupal.org/sandbox/eclipsegc/1441840.git drupal
git checkout 3bc376e5a2f8f6a376560f48745ab6d95a5c2834
An example module that creates a very simple plugin type can be found here:
git clone --recursive --branch info_hooks http://git.drupal.org/sandbox/eclipsegc/1663586.git msg_plugin
The msg_plugin example utilizes hook based discovery. If you would like to see the proposed annotation based discovery (that will hopefully land in a separate patch) you can use this drupal core:
git clone --recursive --branch plugins-annotations http://git.drupal.org/sandbox/eclipsegc/1441840.git drupal
And this example module branch:
git clone --recursive --branch 8.x-1.x http://git.drupal.org/sandbox/eclipsegc/1663586.git msg_plugin
We need feedback on plugin type building on this issue, if you'd like to give feedback on plugin building, please check #1675048: DX: D8 Plugin writing
Eclipse
Comment | File | Size | Author |
---|---|---|---|
#3 | plugins-type-aggregator.patch | 8.38 KB | effulgentsia |
Comments
Comment #1
g089h515r806 CreditAttribution: g089h515r806 commentedI'd like to build a plugin type using plugin system in drupal 8 for field validation validator.
I have build a plugin type for field validation validator in Drupal 7 using ctools, it works great.
Comment #2
bojanz CreditAttribution: bojanz commentedCopying from http://drupal.org/node/1497366#comment-6209878 after examining #1675048: DX: D8 Plugin writing and #1672776: Convert Aggregator Fetchers to Plugins:
- While it makes sense to me that I should somehow "declare" a plugin type, the naming and usage of the PluginType classes in the two issues
made me a bit confused and uneasy. Unsure how the problem should be addressed.
Here's what I saw:
from the first issue, and from the second:
"Messenger" makes me think it's the actual plugin (and the patch in this issue did the same with "Effect').
"FetcherType" also throws me off track, making me think there are multiple types of fetchers, instead of telling me "this is the god object that proxies to both discovery and factory.".
And the variables they are assigned to are always slightly imprecise, since they attempt to describe it as a discovery or a factory mechanism, not both.
Earl had an idea in #1672776: Convert Aggregator Fetchers to Plugins to name the "god object" -> Manager or Arbiter, which would bring clarity but require some reachitecturing.
Perhaps the solution is to just be more verbose:
This brings the question of do we want to mention "plugin" at all in the end user API.
And of course there's always the idea of just splitting the PluginType into two objects (as effulgentsia suggested in #154).
I'm not sure what other logic might live in the PluginType classes, so that might or might not be practical.
Comment #3
effulgentsia CreditAttribution: effulgentsia commentedThanks for the review, bojanz. I'd like to see a few more here before thinking about solutions, but you're hitting on exactly the kind of stuff that I was hoping would surface from this issue.
For those who haven't provided feedback yet, in case it helps, I'm attaching the relevant bit from #1497366-176: Introduce Plugin System to Core. The example module in the issue summary is a great way to onboard to the proposed plugin system, while this patch is a way to see how an existing module implementing a plugin-like system already (aggregator fetchers) needs to change in order to use the standardized plugin system being proposed. As in #2, feel free to post feedback about either the example module or this patch or both.
This patch just deals with the "plugin type writing" part. The corresponding "plugin writing" part is in #1675048-12: DX: D8 Plugin writing.
Comment #4
g089h515r806 CreditAttribution: g089h515r806 commentedI have build a plugin type for field validation. It works, The code could be download at http://drupal.org/node/1677498.
I have a problem, the last argument of construct function in FieldValidationValidator is passing by reference, In Drupal 7, I use ctools, I could get the the class name, then I could call it directly using this code:
$errors which pass by reference works correctly.
When in Drupal 8, I have to using this code:
$errors should pass by reference, but it does not work.
Is there any way that I could use my old method instead of using "->createPluginInstance()".
Here is my code:
validator plugin:
abstract class:
plugin type:
Code from field validation module:
Comment #5
Wim Leersnew FetcherType()
results in a$fetcher_lister
.Nitpick: s/Downloads/Fetches/?
new FetcherType()
results in a$fetcher_factory
. Yet it's an identical instantiation. Very confusing. I'm wondering if there's a better name than "PluginType". I looked at Qt's API design for inspiration, but I could only find explicit "QSomethingFactory" classes. The closest match would be "QSomethingManager" classes. So what about "PluginTypeManager"? You ask the manager to find plugins of a certain type. You also ask it to create an instance.However, I personally think that it does not make too much sense to explicitly write and use something like
FetcherType
. To me, it feels more natural to have a single (dare I say, singleton?)PluginManager
, which you can use to find plugins of a certain type, or rather that implement a certain interface ($pluginManager = new PluginManager(); $fetcher_plugins = $pluginManager->find($interface = Drupal\aggregator\Plugin\Type\FetcherInterface);
). You can also use it to instantiate plug-ins: ($pluginManager = new PluginManager(); $fetcher_plugin = $pluginManager->create($plugin = Drupal\aggregator\Plugin\aggregator\fetcher\DefaultFetcher)
.In my very humble opinion, it then becomes much easier to work with plug-ins. There's less things that you need to know. You only need to know about
PluginManager
and the type/interface of the plug-in you're looking for.I reviewed this without reading previous reviews. Turns out I made the exact same comment as bojan :)
Comment #6
Wim LeersSorry about that.
Comment #7
EclipseGc CreditAttribution: EclipseGc commented@g089h515r806
That's pretty dense, going to take a little while to dig through it.
@Wim
I agree that naming the same class differently twice is sort of a WTF. Dries has consistently been unhappy with whatever we normally named that variable, so I think effulgentsia and neclimdul tried a different approach here naming it based on its use case within the code chunk at the time. We've tossed around the word "manager" (and things like it) and I'm pretty ok with going that route.
I don't see how. In the current solution you have to know what plugin type class handles the plugins you're looking for, and that's it. If we went with the approach I think you just outlined, we still have to essentially know that in order to pass it through a singleton in order to get what would likely just be an instance of the plugin type class back again. Half a dozen of one, six of the other imo. Better to just cut to the chase and be really blatantly obvious about what we're doing.
We had a plugin() singleton very early on in this code, and ultimately killed it in favor of directly calling the class. It ultimately gave us a lot more flexibility, and it requires knowledge only of what class controls this plugin type... which is something you should probably know when dealing with this plugin type anyway. Furthermore, MOST (not all) implementations of a plugin type are going to be done by the developer who wrote the type. It would be an uncommon use case where a developer who didn't write the type needed it again outside it's own administrative areas. (We do this in ctools currently pretty seldom... an example might be putting the equivalent of a ctools "block" (i.e. content_types) on a menu callback by itself... I don't know too many people who've done this or it's equivalent, and to do it in this system, I'm only asking you to find the class name of the managing plugin type).
Eclipse
Comment #8
EclipseGc CreditAttribution: EclipseGc commentedAlso,
@efflugentsia, @Wim Leers, @bojanz,
Can we move discussion that's specific to the aggregator implementation over to: #1672776: Convert Aggregator Fetchers to Plugins
That seems a better spot for it.
Eclipse
Comment #9
Wim LeersI see what you're saying. I think the biggest win would come from calling it something "manager-ish" anyway, so in that regard I'm fine with what you said.
*However*, always having a single entry point into the plug-in system gives developers a familiar (over time) way to use plug-ins. I think purely from a DX POV, my point still stands. But you're absolutely right that my point about "having to know less things" is not actually true.
Comment #10
g089h515r806 CreditAttribution: g089h515r806 commentedI also get an error message when i test annotation:
I download code from:
Then I use the code from :
It works.
I prefer the "annotation based discovery" method and expect that you could commit it to Core.
One question of "annotation based discovery" :
How could we provide some metadata information in Plugin? In Ctools it is in this way:
I understand it now, it is in the annotation:
Comment #11
g089h515r806 CreditAttribution: g089h515r806 commentedMy OS is windows7. Maybe it works at apple OS/ Linux OS.
After i change the code from:
to
The this error mesaage disappears. But I get another error message:
Comment #12
EclipseGc CreditAttribution: EclipseGc commentedI've pushed some new annotation code, why don't you see if it fixes your problem.
Comment #13
EclipseGc CreditAttribution: EclipseGc commentedAdding scotch tag
Comment #14
damiankloip CreditAttribution: damiankloip commentedI have started a sandbox (http://drupal.org/sandbox/damiankloip/1682648) where I am currently converting the core filter module to use the plugin system for it's filters. It's still very much a work in progress, but worth mentioning.
Comment #15
sunComment #15.0
sunadding a checkout for a specific sha1 to guarantee compatilibity
Comment #16
sunMarking these as fixed. We're still iterating over many aspects and are improving them. Check the plugin system component for related issues.
Comment #17.0
(not verified) CreditAttribution: commentedlink filter to issue