As the plugin system gets closer and closer to being committed for D8, I've built a plugin example module to show how it can be used. This is a very simple example at the moment, but should get the basic point across. I wanted to at least point people here at it, even if it's not really ready for inclusion into the Examples module.
http://drupal.org/sandbox/eclipsegc/1663586
Eclipse
| Comment | File | Size | Author |
|---|---|---|---|
| #50 | interdiff.txt | 2.1 KB | m4olivei |
| #50 | 1668362_50.patch | 22.37 KB | m4olivei |
| #49 | 1668362_48.patch | 21.77 KB | mile23 |
| #48 | interdiff.txt | 6.23 KB | mile23 |
| #47 | interdiff.txt | 5.76 KB | m4olivei |
Comments
Comment #1
bobbyaldol commentedComment #2
mile23Marking as postponed for now: #1861598: Examples for Drupal 8 needs relatively stable feature set
Please continue development and discussion as desired.
Comment #3
mile23Comment #4
joachim commentedHere's an example of defining a plugin type.
It defines a Sandwich plugin type, by implementing a SandwichPluginManager. The module also has a single definition of a Sandwich plugin.
What's not yet covered here:
- use of a class other than @Plugin for the annotation. I'm not actually sure yet when you'd want to do that, and it adds complexity to the example anyway.
- use of derivative plugins. Again, these add complexity and I think it's crucial for this example to be simple. I think derivative plugins should be a separate example module. If they are in the same module, then it's harder to work out which parts of the code are needed for which functionality -- and plugin functionality is split over several places, so it's hard to keep track.
There are various TODO comments in the code where I could really use input from someone who knows the plugin system better than I do!
Comment #6
joachim commentedHmmm I don't think this patch is responsible for Drupal\block_example\Tests\BlockExampleTest failing! :D
Comment #7
mile23Looks good, FTMP. Thanks.
But... No tests and too many @todos. :-)
Comment #8
mile23Comment #9
joachim commentedI'll write some tests.
For the TODOs, I need input from, ideally, some of the brains behind the Plugin API on D8 -- because they are things I simply don't know or understand. If someone can provide answers here to the questions in the TODOs, I'll happily incorporate them into the code comments and reroll the patch.
Comment #10
joachim commentedNew patch with test.
Comment #12
joachim commentedI found a bug in the plugin manager constructor.
Comment #13
mile23...
Comment #14
mile23Comment #16
longwaveNot sure this needs explaining here in particular; "namespace" and "use" are standard PHP OO constructs nowadays.
In a nutshell, this is correct; the PluginManager constructor declares the namespace prefix of the plugins that it manages.
+ * Note that this array may NOT have a terminal comma, unlike PHP.This is no longer correct, terminal commas are now allowed in annotations.
+ * @Plugin(It is now recommended that plugins define their own plugin-specific annotations, by implementing a class in the \Drupal\module\Annotation namespace. This lets them declare and document the keys used in that specific plugin.
No, the annotation should only be used for metadata that is specifically required to instantiate the plugin, or for example data that might be needed to display a list of all available plugins where the user selects one. This means many plugin annotations can be reduced to a plugin ID, a label and perhaps a description.
Arguments beginning with @ are the names of other services are being injected into this service. Many common ones are found in /core/core.services.yml. More docs on this can be found at https://drupal.org/node/2133171
Comment #17
joachim commentedThanks!
Here's a new patch with those changes, and also some updating for changes in D8.
Comment #19
socketwench commentedFixed plugin manager service def, routing, controller.
Comment #21
socketwench commentedFixed broken Plugin test. This patch will still turn red because of existing problems in other submodules. (We really need to fix those.)
EDIT: SPELLING.
Comment #23
mile23Branch failures get very high priority when I'm done traveling.
Also patch reviews. :-)
But mostly, thanks for sticking with it.
Comment #24
socketwench commented21: 1668362.21.examples.plugin-type-example-module.patch queued for re-testing.
Retesting because of https://drupal.org/node/2262989
Comment #25
mile2321: 1668362.21.examples.plugin-type-example-module.patch queued for re-testing.
Comment #26
mile23Docs don't match arguments.
Ideally we'd have @see cache_example,
Comment #27
socketwench commentedComment #28
mile23Here's a very incomplete patch with the PSR-4 changes, and the addition of a *.menu_links.yml file.
Still needs a test for the menu links, and also: It fails to display its description page. Is going to need a bunch of work still. (I ran out of time last night.)
Comment #29
mile23Comment #31
cgalli commentedHey Mile, if you agree, I will take care of this module over the coming weeks. With the support of berdir...
Comment #32
mile23Sure. You and @bobbyaldol can arm-wrestle for it if he's still interested. :-)
Comment #33
m4oliveiHere's an updated patch that should work with the latest D8. A few thing have changed since this last patch that I can tell:
* DefaultPluginManager class now also takes the name of an interface. It uses this to force plugins to adhere to it.
* DefaultPluginManager::setCacheBackend() method arguments changed
* I also make the plugin_type_example.routing.yml file consistent with others in the module.
I'll continue working on this as I have time and hopefully round it out, finishing up the remaining TODO's as best I know how. For now though, this patch makes it so that it'll actually work.
Comment #34
mile23Comment #36
mile23Looks good. Here's some review:
I see a menu_links.yml and a route, but I don't see the menu when I enable the module.
Also: Needs a link in the toolbar (from examples module).
Remove the explanation of examples, and add a brief walk-through of what the module demonstrates, and where to see each thing.
Do we really need this constructor?
Nice to have an interface.
Yah, coding standards. :-)
Also, any narrative explanation of why you need certain services or dependencies should be in the docblock, with only a brief description in @param.
Marked as optional, but no default is provided in the method signature.
Is this relevant?
Comment #37
m4oliveiThanks for the review!
I think I covered everything. I also combed through all the files and updated some docs and made some coding standards tweaks. Responses to your comments:
1. I've banged my head against the wall on this. I don't know why it's not showing up in the menu. Help?
2. Done
3. Nope, gone.
4. Agreed, created.
5. Done. I think I did anyhow.
6. Updated these docs based on some other core plugin managers.
7. Couldn't hurt, I've added some commentary there.
I also added a second plugin, ExampleMeatballSandwich. Thought it better demonstrated plugin types to have more than one. It also helps show off the alter hook better.
Comment #38
mile23You can set the issue to 'needs review' and the testbot will start. :-)
Comment #41
m4oliveiAhh, right. Here is an updated patch to fix the tests. Removed a getInfo method, which seemed like an artifact, b/c the description seems to come from the class docblock. Also set the test $profile to 'minimal' b/c that's the only way I could get the
testPluginExamplePagetest to pass, otherwise it was returning 403 on that first assertion. Anyhow. Crossing fingers for test success.Comment #42
m4oliveiComment #45
m4oliveiComment #46
mile23Cool, thanks.
A few more things:
Wrap at 80. It's OK if the class name and method don't wrap.
Add a description of what this page is showing, referencing the plugin classes.
We should inject this service.
Comment #47
m4oliveiThanks again for the feedback. Really appreciate it. TIL how to inject a service into a controller. Updated patches attached.
Comment #48
mile23I did some minor updates and coding standards stuff. Patch attached.
Also:
So the docblock here should only say 'Implements hook_sandwich_info_alter().' We also need an api.php file because we're defining a hook. Docs: https://www.drupal.org/coding-standards/docs#hooks
Comment #49
mile23Comment #50
m4oliveiapi.php file created and doc block for plugin_type_example_sandwich_info_alter() updated. Also wrapped a string in
t().Comment #52
mile23Great, thanks!
Committed, with some coding standards fixes.
Comment #53
m4oliveiw00t!