Problem/Motivation

This issue is a followup for #1535868: Convert all blocks into plugins.

  • The plugin system uses the : character as a delimiter for derivative IDs.
  • The blocks-as-plugins patch introduces the use of derivatives for:
    • Per-theme block instances
    • Custom blocks
    • Menu blocks
    • Views block displays
  • To extract the plugin ID from the block ID, the blocks-as-plugins patch includes a lot of code like:
    list(, $bid) = explode(':', $this->getPluginId());
    
  • There is no test coverage in the plugin system for derivative IDs generally, nor any test coverage in the blocks patch to ensure that multiple derivatives work properly together (e.g. per-theme instances of custom blocks).

Proposed resolution

  • Add methods to the plugin system and/or the block system that extract the base ID and derivative ID from a plugin's full ID.
  • Add unit test coverage for the methods in Drupal\system\Tests\Plugin\DerivativeTest, including for derivatives of derivatives.
  • Add functional test coverage for the methods' implementations in the block system.

Remaining tasks

Related issues

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

xjm’s picture

Issue summary: View changes

Updated issue summary.

xjm’s picture

Issue summary: View changes

Updated issue summary.

xjm’s picture

Issue summary: View changes

Updated issue summary.

xjm’s picture

Title: Provide API method(s) for retrieving base plugin and derivative names from block plugin IDs » Provide and use API methods for retrieving base plugin and derivative names from block plugin IDs

There are at least two methods, I guess; one for the base plugin ID and one for the derivative ID.

In the course of trying to figure out where generic methods for the plugin system would go, I discovered that DerivativeDiscoveryDecorator already has decodePluginId() and encodePluginId(). We're just not using them.

xjm’s picture

Also, it looks to me like decodePluginId() erroneously assumes that there's only ever one derivative. I think it should be taking the last segment after a colon rather than the first? Or perhaps there should be separate methods for the base plugin ID, the parent derivative, and the current derivative?

xjm’s picture

Issue summary: View changes

Updated issue summary.

xjm’s picture

Issue summary: View changes

Updated issue summary.

xjm’s picture

Issue summary: View changes

Updated issue summary.

xjm’s picture

Status: Postponed » Active
xjm’s picture

Issue tags: +Block plugins
jibran’s picture

I tried to understand the problem. I think we can create wrapper functions of getPluginId() like
getBasePluginId()
getDerivativeId()

jibran’s picture

Status: Active » Needs review
FileSize
1.72 KB

Here is the start.

Status: Needs review » Needs work
Issue tags: -Needs tests, -VDC, -Blocks-Layouts, -Block plugins

The last submitted patch, 1874498-6.patch, failed testing.

jibran’s picture

Status: Needs work » Needs review

#6: 1874498-6.patch queued for re-testing.

Status: Needs review » Needs work
Issue tags: +Needs tests, +VDC, +Blocks-Layouts, +Block plugins

The last submitted patch, 1874498-6.patch, failed testing.

tim.plunkett’s picture

Many things implement PluginInspectionInterface without extending PluginBase

And many of them don't use derivatives.

jibran’s picture

Status: Needs work » Needs review
FileSize
1.7 KB
1.09 KB

Ok got it. Removed the changes in PluginInspectionInterface.

tim.plunkett’s picture

It still needs an interface somewhere. Maybe a new one that all classes with 'derivative' in the annotation *should* implement? Not sure. Traits would probably have been useful here...

benjy’s picture

Status: Needs review » Needs work

As per @tim.plunkett's comment, setting this back to "needs work"

neclimdul’s picture

seems related to this ancient issue #1678612: Make getBasePluginId and getDerivativeId static and public. There doesn't really seem to be a stated problem here though. The "problem" in the summary is a stating of facts and I'm not going to try and figure out what from that 400 comment thread we're talking about. Could we be more clear about the problematic use case?

tim.plunkett’s picture

Status: Needs work » Needs review
Issue tags: +Needs issue summary update
FileSize
9.64 KB

Hopefully this patch will illustrate the problem this solves. The issue summary should still be updated.

tim.plunkett’s picture

And yes, I know that I am contradicting myself in #10, but I think that it's better to add these methods here than to force another interface on, at least without traits.

Status: Needs review » Needs work

The last submitted patch, plugin-1874498-16.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
10.33 KB
2.29 KB

Okay, nevermind. Here's the middle ground: 2 interfaces, but the base class just implements both. You're not forced into it.

Status: Needs review » Needs work

The last submitted patch, plugin-1874498-18.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
1.15 KB
11.48 KB

I hate BlockTemplateSuggestionsUnitTest.

dawehner’s picture

Issue tags: -Needs tests +PHPUnit
FileSize
14.55 KB

Because this needed a rerole.

Status: Needs review » Needs work
Issue tags: -Needs issue summary update, -PHPUnit, -VDC, -Blocks-Layouts, -Block plugins

The last submitted patch, plugin-1874498-21.patch, failed testing.

neclimdul’s picture

Status: Needs work » Needs review
Issue tags: +Needs issue summary update, +PHPUnit, +VDC, +Blocks-Layouts, +Block plugins

#21: plugin-1874498-21.patch queued for re-testing.

tim.plunkett’s picture

Priority: Normal » Major
Issue tags: +DX (Developer Experience)
FileSize
912 bytes
14.54 KB

Rerolled. Let's stop propagating this ugliness.

Status: Needs review » Needs work

The last submitted patch, plugin-1874498-24.patch, failed testing.

Xano’s picture

dawehner’s picture

Does this overlap with #2035345: Reconsider whether to use ':' as separator for derivative plugins?

I would say so as the other issue moves the responsibility to define the separator into another object.

tim.plunkett’s picture

Status: Needs work » Needs review
FileSize
16.32 KB
1.02 KB

There was a new test added recently.

tim.plunkett’s picture

FileSize
16.32 KB

Reroll.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community
  1. +++ b/core/lib/Drupal/Component/Plugin/PluginBase.php
    @@ -58,6 +58,29 @@ public function getPluginId() {
    diff --git a/core/lib/Drupal/Component/Plugin/PluginInspectionInterface.php b/core/lib/Drupal/Component/Plugin/PluginInspectionInterface.php
    
    diff --git a/core/lib/Drupal/Component/Plugin/PluginInspectionInterface.php b/core/lib/Drupal/Component/Plugin/PluginInspectionInterface.php
    index 31e5e46..71fee3b 100644
    
    index 31e5e46..71fee3b 100644
    --- a/core/lib/Drupal/Component/Plugin/PluginInspectionInterface.php
    
    --- a/core/lib/Drupal/Component/Plugin/PluginInspectionInterface.php
    +++ b/core/lib/Drupal/Component/Plugin/PluginInspectionInterface.php
    
    +++ b/core/lib/Drupal/Component/Plugin/PluginInspectionInterface.php
    +++ b/core/lib/Drupal/Component/Plugin/PluginInspectionInterface.php
    @@ -30,4 +30,5 @@ public function getPluginId();
    
    @@ -30,4 +30,5 @@ public function getPluginId();
        *   plugin manager.
        */
       public function getPluginDefinition();
    +
     }
    

    Sort of out of scope but I don't care.

  2. +++ b/core/modules/block/lib/Drupal/block/Tests/BlockPreprocessTest.php
    @@ -10,9 +10,9 @@
    -class BlockPreprocessUnitTest extends WebTestBase {
    

    HAHAH

catch’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs issue summary update, +DX (Developer Experience), +PHPUnit, +VDC, +Blocks-Layouts, +Block plugins

The last submitted patch, plugin-1874498-29.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
FileSize
16.19 KB

Rerolled

ParisLiakos’s picture

Status: Needs review » Needs work
+++ b/core/tests/Drupal/Tests/Component/Plugin/PluginBaseTest.php
@@ -0,0 +1,115 @@
+  public function testGetPluginId() {
...
+  public function testGetBasePluginId() {
...
+  public function testGetDerivativeId() {

those should use data providers to avoid code duplication

also, no longer applies

dawehner’s picture

Status: Needs work » Needs review
FileSize
5.97 KB
16.47 KB

Good point.

dawehner’s picture

Issue summary: View changes

Updated issue summary.

benjy’s picture

A few commas missing. I'll do a proper review in the day few days.

  1. +++ b/core/tests/Drupal/Tests/Component/Plugin/PluginBaseTest.php
    @@ -0,0 +1,134 @@
    +      array()
    

    Missing comma.

  2. +++ b/core/tests/Drupal/Tests/Component/Plugin/PluginBaseTest.php
    @@ -0,0 +1,134 @@
    +      array()
    

    here

  3. +++ b/core/tests/Drupal/Tests/Component/Plugin/PluginBaseTest.php
    @@ -0,0 +1,134 @@
    +      array()
    

    here

  4. +++ b/core/tests/Drupal/Tests/Component/Plugin/PluginBaseTest.php
    @@ -0,0 +1,134 @@
    +      array('value', array('key' => 'value'))
    

    here

dawehner’s picture

Issue summary: View changes
FileSize
16.38 KB

Good catches!

aspilicious’s picture

Status: Needs review » Reviewed & tested by the community

aspilicious’s picture

Looks good to me.

Xano’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/lib/Drupal/Component/Plugin/PluginBase.php
    @@ -58,6 +58,29 @@ public function getPluginId() {
    +    if (strpos($plugin_id, ':')) {
    

    I wonder if it might not be a good idea to use a constant for the separator, since this is also used by DerivativeDiscoveryDecorator and the whole derivative system currently relies on the separator being a colon. See #2035345: Reconsider whether to use ':' as separator for derivative plugins as well.

  2. +++ b/core/modules/block/lib/Drupal/block/Tests/BlockPreprocessUnitTest.php
    +++ b/core/modules/block/lib/Drupal/block/Tests/BlockPreprocessUnitTest.php
    @@ -2,7 +2,7 @@
    
    @@ -2,7 +2,7 @@
     
     /**
      * @file
    - * Contains \Drupal\block\Tests\BlockPreprocessUnitTest.
    + * Contains \Drupal\block\Tests\BlockPreprocessTest.
      */
     
     namespace Drupal\block\Tests;
    @@ -10,9 +10,9 @@
    
    @@ -10,9 +10,9 @@
     use Drupal\simpletest\WebTestBase;
     
     /**
    - * Unit tests for template_preprocess_block().
    + * Web tests for template_preprocess_block().
      */
    -class BlockPreprocessUnitTest extends WebTestBase {
    +class BlockPreprocessTest extends WebTestBase {
    

    The class name does not match the file name.

dawehner’s picture

Status: Needs work » Needs review
FileSize
16.35 KB
2.08 KB

Thank you for the review.

andypost’s picture

41: plugin-1874498.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, 41: plugin-1874498.patch, failed testing.

dawehner’s picture

41: plugin-1874498.patch queued for re-testing.

benjy’s picture

Status: Needs work » Needs review

Status was wrong.

benjy’s picture

FileSize
16.37 KB

Re-rolled. +1 for RTBC from me.

andypost’s picture

Status: Needs review » Reviewed & tested by the community

It works!

catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed to 8.x, thanks!

Status: Fixed » Closed (fixed)

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