Problem/Motivation
The plugin system allows plugins to specify a class to provide plugin definitions based on the definition of the original plugin class. These definitions are called derivative plugin definitions. However, the class that provides them is called the derivative class, while it itself is not a derivative at all.
This confusion makes it hard to explain how the plugin system works, and to provide exceptions that are specific to derivative plugins or those classes that provide their definitions.
Proposed resolution
Rename derivative classess to derivers, as what they do is derive plugin definitions.
Remaining tasks
None.
User interface changes
None.
API changes
- The
derivativeplugin definition key is renamed toderiver. DerivativeInterfaceis renamed toDeriverInterface.ContainerDerivativeInterfaceis renamed toContainerDeriverInterface.DerivativeBaseis renamed toDeriverBase.
These are all naming changes. There are no functional changes.
Original report by @username
Posted by xjm
Problem/Motivation
This is a followup for #1535868: Convert all blocks into plugins.
- Currently, the plugin system has the convention that derivative classes have the same name as the class for which they provide derivative definitions, e.g.,
Drupal\custom_block\Plugin\block\block\CustomBlock
and
Drupal\custom_block\Plugin\Derivative\CustomBlock - This is merely a naming convention and not a requirement, since the derivative class is specified in the plugin definition (e.g. in the annotation with annotated discovery).
- The OO naming conventions specify that:
Classes and interfaces should have names that stand alone to tell what they do without having to refer to the namespace, read well, and are as short as possible without losing functionality information or leading to ambiguity
Having two closely related classes with exactly the same name does not meet this requirement.
- It's especially confusing when one does not already have a thorough understanding of the plugin system. I was reviewing #1535868: Convert all blocks into plugins for weeks before I "got" it. If the classes had been named differently, it would have saved me some time.
Proposed resolution
- Come up with a different naming convention for derivative classes, something like, e.g.,
CustomBlockDerivative. - Rename derivative classes according to this standard.
| Comment | File | Size | Author |
|---|---|---|---|
| #117 | drupal_1875996_117.patch | 80.05 KB | neclimdul |
| #112 | drupal_1875996_112.patch | 80.05 KB | xano |
| #111 | interdiff.txt | 5.22 KB | xano |
Comments
Comment #1
xjmComment #2
tim.plunkettThis wreaks havoc on my vim ctags. I'm +1 to adding 'Derivative' as a suffix
Comment #3
jhodgdonWe do have an issue somewhere about reviewing all class names and making sure they follow the standards. There are a ton with problems... this should probably be put as a sub-issue or duplicate of that other issue... Let's see, where is it?
#1809930: [meta] Many core class names violate naming standards
Comment #4
tim.plunkettThere were already several classes suffixed with "Deriver", which is more correct, since this class does the deriving, it itself is not the derivative.
Comment #6
tim.plunkettI forgot there were string references to those files.
Comment #7
jhodgdonUm... What do these "Deriver" classes actually do? The name "Deriver" to me says that the function of the class is to derive something. Is that the case? I really don't know what these classes are. What are they derivatives of or what are they deriving?
Anyway, lines like this just seem very odd to me:
The interface is called "Derivative" and the class is called "Deriver"... Hm...
Comment #8
tim.plunkettI intend to open up an issue to rename DerivativeInterface to DeriverInterface.
An example of a Deriver is MenuBlock (now MenuBlockDeriver). It loops through all of the menus on a site, and provides a derivative block plugin, one per menu.
The idea is that you don't need to write a whole new plugin for each menu you add, you have one deriver that has its own logic for determining its derivatives.
Comment #9
jhodgdonOK, then the name Deriver makes sense to me. Can't we do the interface in this same patch?
Comment #10
tim.plunkettSure!
Comment #11
jhodgdonThe only slightly weird thing left that I see is that the namespaces still have "Derivative" in them:
The method names also confused me, but when I read the documentation I think I agreed that they should still have Derivative in them, not Deriver. But I will add that the docs are using "id" all over, and I don't think they are talking about psychology (look it up: "id" is like ego, superego, id, and "ID" means identifier, one of my pet documentation peeves, but anyway that is a separate issue.)
Comment #12
jhodgdonThis is not really a docs issue.
Comment #13
neclimdulI had the reverse reaction of jhodgdon. The namespace is Derivative and the interface is Deriver?
Comment #14
xjmYeah the word "Deriver" seems a little goofy to me in general.
Comment #15
tim.plunkettWell the classes do the deriving. The derivatives themselves are whatever those classes find, like the values in the database that represent a custom block.
So both the namespace and the interface should be changed...
Comment #16
jhodgdonWait a minute. The main purpose of a particular Block derivative class is to define/provide a block, correct? So it seems like the class name shouldn't have derivative or deriver or anything else like that in it. It should just be called the FooBarReallyCoolBlock class or something like that? I mean, it's possible that the way that the class manages to provide a block for use in a site is by being a derivative of another class, but class names should tell the purpose of the class (why it exists), not some detail of the internal mechanisms by which it gets its work done, right?
Comment #17
xjmNo, the purpose of a derivative class is to extend an existing plugin to provide multiple definitions. So, for example, we have a MenuBlock plugin that provides the basic menu block plugin definition. And then the MenuBlockDerivatives (or whatever) class returns definitions of MenuBlock for each menu. Not all plugins need derivatives, though--for example, the system Powered By Drupal block is only ever one thing.
Comment #18
jhodgdonAh, OK. For the situation in #17, it seems like there should be:
MenuBlock (defines the plugin type for blocks displaying menus)
MenuBlockGenerator (generates a menu block definition for each defined menu)
Generator sounds like a reasonable name to me, but maybe there is a standard computer science term for this pattern that we should use instead?
Comment #19
Crell commentedI don't know of a standard CS term, but would that get confused with the UrlGenerator, which is colloquially just called "the generator"?
(Once again, English has insufficient nouns to keep up with Drupal.)
Comment #20
jhodgdonI am not sure why it would get confused.
Comment #20.0
jhodgdonUpdated issue summary.
Comment #20.1
xjmRemoving myself from the author field so that I can unfollow issues. --xjm
Comment #21
xanoRe-roll, and using deriver instead of the current inconsistent derivative and derivative fetcher.
Comment #22
jhodgdonNot all of the files got renamed the same as the classes in that patch. For instance, the first one at the top.
Comment #24
xanoComment #26
xanoRe-roll.
Comment #27
xanoComment #29
xano26: drupal_1875996_26.patch queued for re-testing.
Comment #31
xano26: drupal_1875996_26.patch queued for re-testing.
Comment #32
xano26: drupal_1875996_26.patch queued for re-testing.
Comment #33
xanoRe-roll, and I renamed
getBasePluginId()togetBaseId()andgetDerivativePluginId()togetDerivativeId()on\Drupal\Core\Plugin\Discovery\ContainerDeriverInterfaceper @EclipseGc's request.Comment #36
xano33: drupal_1875996_33.patch queued for re-testing.
Comment #38
xanoComment #40
xanoComment #42
xanoComment #43
xano40: drupal_1875996_40.patch queued for re-testing.
Comment #45
xanoHmmz. I can't reproduce any of these errors locally and the code looks fine too.
Comment #46
xanoMeh, wrong
.gitignoreconfiguration locally.Comment #48
xano46: drupal_1875996_46.patch queued for re-testing.
Re-testing, as I cannot reproduce the failures locally.
Comment #49
xanoTests pass now.
Comment #50
neclimdulCan we update the summary? 73k is a lot to review without direction.
Comment #51
xanoComment #52
xanoComment #53
neclimdulI've run out of time today to look at the code but I agree with the documented API changes. +1
Comment #54
xano46: drupal_1875996_46.patch queued for re-testing.
Comment #56
xanoComment #58
xanoRe-roll because of changes in
\Drupal\Tests\Core\Plugin\Discovery\DerivativeDiscoveryDecoratorTest.Comment #60
xanoComment #62
xanoComment #63
xano62: drupal_1875996_62.patch queued for re-testing.
Comment #65
Jalandhar commentedUpdating with reroll. Please review.
Comment #66
xanoWhich parts did not apply?
Comment #67
Jalandhar commented@xano,
For below.
-----------------------------
diff --git a/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php
index 15cb1d8..983d84f 100644
--- a/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php
+++ b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemMenuBlock.php
@@ -17,7 +17,7 @@
* id = "system_menu_block",
* admin_label = @Translation("Menu"),
* category = @Translation("Menus"),
- * derivative = "Drupal\system\Plugin\Derivative\SystemMenuBlock"
+ * deriver_class = "Drupal\system\Plugin\Derivative\SystemMenuBlock"
* )
*/
class SystemMenuBlock extends BlockBase {
diff --git a/core/modules/system/lib/Drupal/system/Plugin/Derivative/SystemMenuBlock.php b/core/modules/system/lib/Drupal/system/Plugin/Derivative/SystemMenuBlock.php
index 72a4c49..39cef36 100644
--- a/core/modules/system/lib/Drupal/system/Plugin/Derivative/SystemMenuBlock.php
+++ b/core/modules/system/lib/Drupal/system/Plugin/Derivative/SystemMenuBlock.php
@@ -7,9 +7,9 @@
namespace Drupal\system\Plugin\Derivative;
-use Drupal\Component\Plugin\Derivative\DerivativeBase;
+use Drupal\Component\Plugin\Deriver\DeriverBase;
use Drupal\Core\Entity\EntityStorageControllerInterface;
-use Drupal\Core\Plugin\Discovery\ContainerDerivativeInterface;
+use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
diff --git a/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsBlock.php b/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsBlock.php
index 9541124..05c7dc4 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsBlock.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsBlock.php
@@ -8,7 +8,7 @@
namespace Drupal\views\Plugin\Derivative;
use Drupal\Core\Entity\EntityStorageControllerInterface;
-use Drupal\Core\Plugin\Discovery\ContainerDerivativeInterface;
+use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
diff --git a/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsExposedFilterBlock.php b/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsExposedFilterBlock.php
index 29439a6..3e08fd0 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsExposedFilterBlock.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsExposedFilterBlock.php
@@ -7,7 +7,7 @@
namespace Drupal\views\Plugin\Derivative;
-use Drupal\Core\Plugin\Discovery\ContainerDerivativeInterface;
+use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Drupal\Core\Entity\EntityStorageControllerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
--------------------------------------
Comment #68
xanoThanks! Next time you can also use the
<code>tag when you paste code, or use http://pastebin.com if the code is more than a few lines.Comment #69
damiankloip commentedHow come this is a part of this issue? Doesn't seem like a requirement for the derivative > deriver change?
Comment #70
xanoSomeone asked me to make that consistent in this issue, as we have
getDerivativeId()as well. That person may have been EclipseCG, but I am not sure.Comment #71
neclimdulComment trail points to Kris #1875996-33: Reconsider naming conventions for derivative classes
Comment #72
alexpottdrupal8-reconsider_naming_conventions_for_derivative_classes-1875996-65.patch no longer applies.
Comment #73
rajendar reddy commentedUpdating patch with reroll. Please review.
Comment #74
xanoComment #76
Jalandhar commented73: drupal8-reconsider_naming_conventions_for_derivative_classes-1875996-73.patch queued for re-testing.
Comment #77
Jalandhar commentedThere might be a bot issue. Back to RTBC, as per #74.
Comment #78
xjmThis absolutely needs some change record action. I think we both want a draft change record here, and a list of all the existing change records that need to be updated for this so we can update them after this goes in. Thanks!
Comment #79
xjmComment #80
xanoThe change records that will need to be changed are https://drupal.org/node/2165243 and https://drupal.org/node/2044515.
Comment #81
xano73: drupal8-reconsider_naming_conventions_for_derivative_classes-1875996-73.patch queued for re-testing.
I also added a change record draft.
Comment #83
xanoRe-roll.
Comment #84
xjmThanks @Xano!
Comment #85
xano83: drupal_1875996_83.patch queued for re-testing.
Comment #86
xano83: drupal_1875996_83.patch queued for re-testing.
Comment #88
xanoRe-roll.
Comment #89
xjmComment #90
xanoMarking this as a DX improvement, because we currently do not properly distinguish between derivative plugins and derivers in terms of jargon.
Comment #91
xanoRe-roll.
Comment #92
xano91: drupal_1875996_91.patch queued for re-testing.
Comment #93
neclimdulSo I've actively been trying to avoid driving this issue and let the community figure out how to name this. It feels like we're getting to a consensus but before we move to RTBC I want to go ahead and get this out.
I'm don't think this namespace change is useful. When listening to people talk about plugins outside this discussion, I've heard things like "use Derivatives" and "those are implemented by Derivatives." They aren't talking about the class, they're talking about the concept. Derivers are the tool and that does seem to make the language better, but Derivative is the concept. I don't think we'll probably have any other classes in the namespace, but I do think it would be better to leave the namespace the conceptual term even if it doesn't match the class.
Comment #94
xanoThat makes sense.
Comment #95
tim.plunkett+1 for #93
Comment #96
xanoLet's also get rid of the
_classsuffix ofderiver_class, as we don't do that anywhere else. For all we know we'll support derivers to be services in the future.Comment #97
xanoRe-roll. Will fix the naming issues in the following patch.
Comment #99
xanoFixed the test failure, the namespace, and the annotation property name.
Comment #100
xanoComment #102
xanoComment #103
xano102: drupal_1875996_102.patch queued for re-testing.
Comment #104
neclimdulLooks good to me. I'd say the change record updates can happen after commit? I could be wrong but going to be bold and RTBC it.
Comment #105
xjmYep, I think so: Per @Xano:
Those are just minor corrections that can be made once the patch is committed and we publish https://www.drupal.org/node/2257811.
Comment #107
chx commentedComment #108
tim.plunkettIn #2287097: Use block template to render blocks, we're having problems because BlockPluginInterface does not implement DerivativeInspectionInterface.
However, we call it indiscriminately, and BlockBase implements all of the methods.
So instead of cheating in all of those docs, I'l like to see this fixed in place.
Assigning to @neclimdul for final sign off.
Comment #109
neclimdulThere are a ton of @var comments in here. I'm not sure we need all them but we don't have guidelines so what ever.
"Creates a new instance" should be sufficient. It confuses me if only because its creating a new object, not a class. #nitpickofthemonth
I'm going to make an exception for this @var which seems a bit useless. I'm aware phpstorm doesn't parse that which is unfortunate but its one method call and its really obvious what's happening so I don't see the point. It doesn't actually document anything useful.
Fully qualified?
Fully qualified?
Again...
Comment #110
xanoIt does, as it lets PhpStorm (and perhaps other IDEs) know the variable type. Without the comment, PhpStorm wouldn't know, and it would mark subsequent method calls as invalid.
I blame the system...
Comment #111
xanoComment #112
xanoHere is the same patch, but with renames, so it should be slightly smaller and easier to read.
Comment #113
neclimdulSo, like I said, there are no guidelines but I still want to be clear. My view is your IDE is there to help the developer read code and we don't need help reading
is_subclass_of.I guess I see this as doing something like this which would never fly.
I'm not going to stop this issue on such a unclear doc issue though, RTBC.
Comment #114
xanoThis is indeed not part of our docs. However, PhpStorm doesn't use is_subclass_of() for type hints, so I tend to add @var comments to help me see if the code is correct in the blink of an eye. I've found doing this helps me find problems much more quickly.
Comment #116
neclimdulstraight reroll
Comment #117
neclimdula patch with some content...
Comment #118
tim.plunkettLooks good to me!
Comment #120
dries commentedGood first step so committed to 8.x. Thanks everyone! This patch didn't rename
Drupal\block_content\Plugin\Derivative\BlockContent. Per the original issue summary, do we still want to do that, since there's also aDrupal\block_content\Entity\BlockContent? Would generically adding aDeriversuffix to all deriver classes make sense?Comment #121
tstoecklerFollow-up: #2295571: Bogus CustomBlock class in repo
(This is not the follow-up so not removing the "needs follow-up" tag.)