Currently, you have to implement an empty class for any local action plugin. This is a bit weird, you are then just using the empty class for the annotation. It makes sense, similar to routes, to have YAML discovery for these, then static local actions just get added into a $module.local_actions.yml file. This seems like better UX, as people can then actually create a plugin class for dynamic local actions.

Here is a rough initial patch, to get things rolling. No tests yet. It contains one conversion of the views UI add view link.

Also, the name StaticLocalActionDeriver is the first thing that came into my head, so thoughts on better names for that are most welcome and... I think it would might make sense to move getRouteName() and getTitle() methods from LocalActionBase into this new class?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

fubhy’s picture

+++ b/core/lib/Drupal/Core/Menu/LocalActionManager.phpundefined
@@ -122,6 +122,7 @@ public function getActionsForRoute($route_name) {
+

Dude, what's with these weird unrelated changes. Maaaan!

+++ b/core/lib/Drupal/Core/Menu/Plugin/Derivative/StaticLocalActionDeriver.phpundefined
@@ -0,0 +1,116 @@
+   * Constructs a ViewsBlock object.

No... Just... No.

+++ b/core/lib/Drupal/Core/Menu/Plugin/Derivative/StaticLocalActionDeriver.phpundefined
@@ -0,0 +1,116 @@
+   * @param \Drupal\Core\Entity\EntityStorageControllerInterface $view_storage_controller
+   *   The entity storage controller to load views.

No, no, no...

damiankloip’s picture

Thanks! All valid comment related screw ups. I will see how tests get on, then reroll in a bit.

pwolanin’s picture

Seems like we need a more generic framework for using yaml to define other-wise empty class definitions as derivatives of a base class?

damiankloip’s picture

FileSize
3.54 KB
6.89 KB

That should be taken care of elsewhere, at the moment we don;t have that, So that shouldn't hold this up. The current (rushed) implementation is going to have a whole load of empty classes if we leave it...

So I think it makes sense to move the methods I mentioned above into the new plugin class. This only really makes sense if we're using static titles anyway.

EDIT: wrong patch comment #...

damiankloip’s picture

Sorry, the getRoutename() method doesn't make sense to move aswell.

fubhy’s picture

Changing the base class now is an API change. Let's not do that.

damiankloip’s picture

That thought didn't even cross my mind, you're right. Let's make this as easy as possible. I will leave it a bit and let the bot get on with its business.

Status: Needs review » Needs work

The last submitted patch, 2050227-5-real.patch, failed testing.

damiankloip’s picture

Status: Needs work » Needs review
FileSize
1.11 KB
6.3 KB

Let's move that method back.

dawehner’s picture

Issue tags: +MenuSystemRevamp
+++ b/core/lib/Drupal/Core/Menu/Plugin/Derivative/StaticLocalActionDeriver.phpundefined
@@ -0,0 +1,117 @@
+class StaticLocalActionDeriver implements ContainerDerivativeInterface {

Ohhh I would have assumed it to use a different discovery mechanism. This one then could have been reused on local tasks as well.

fubhy’s picture

Ohhh I would have assumed it to use a different discovery mechanism. This one then could have been reused on local tasks as well.

Together with #2050289: Add class to make yaml discovery reusable I think the approach of using a derivative is better. Not sure why, I just find it nice :).

dawehner’s picture

Having multiple way to define such way potentially confuses people.

On the other hand doing it like it is proposed here, would really easy allow us to not change the API for now.

fubhy’s picture

+++ b/core/lib/Drupal/Core/Menu/LocalActionBase.phpundefined
@@ -81,7 +81,6 @@ public function getRouteName() {
-    // Subclasses may pull in the request or specific attributes as parameters.

Why remove that damiboy? :(

+++ b/core/lib/Drupal/Core/Menu/Plugin/Derivative/StaticLocalActionDeriver.phpundefined
@@ -0,0 +1,117 @@
+   * Implements \Drupal\Component\Plugin\Derivative\DerivativeInterface::getDerivativeDefinition().

inheritdoc please, bro.

+++ b/core/lib/Drupal/Core/Menu/Plugin/Derivative/StaticLocalActionDeriver.phpundefined
@@ -0,0 +1,117 @@
+    // @todo Replace with a generic YAML discovery solution when we have one.

Maybe add issue number?

Otherwise looking good! Thanks!

damiankloip’s picture

Thanks for the review fubhy, I've made those changes.

Daniel: I think this will have alot of similarities to what we do with routes, and services, so from a DX point of view I think this is a good thing. People will have to do the same, if they want to dynamically add routes, for example. Well, not plugins, but you know what I mean. This makes it alot easier to define simple actions; as well as not having lots of plugin classes just being used for their definition - this is pretty much what derivatives are for right? :)

dawehner’s picture

I don't disagree with the better/easier DX at the moment, but I want to raise the point that having two basically equal levels will maybe confuse people.

fubhy’s picture

Status: Needs review » Reviewed & tested by the community

but I want to raise the point that having two basically equal levels will maybe confuse people

You mean because you can provide a 'static' local action by providing a empty annotation class or a yaml file? Well, we can't really prevent that from happening, can we? Not without breaking the API at least.

I think this is good to go. Let's do the same for local tasks.

fubhy’s picture

#2050919: Replace local task plugin discovery with YamlDiscovery

Now that I think of it, should we do local tasks and actions with a single .yml file instead of two?

damiankloip’s picture

I'm not sure about that right now, I haven't given it much thought. Certainly something worth considering though. I think we should move in easy stages, and see how we get on with this patch and the issue in #17, then talk about potential considation maybe?

pwolanin’s picture

If we are going this we should make sure the discovery code is generic and use it as well for local tasks

damiankloip’s picture

@pwolanin, see the @todo in the patch, and #2050289: Add class to make yaml discovery reusable.

If we want to share any more code than that I would suggest a follow up to do this to local actions/tasks in general as it looks like the LocalACtionBase and LocalTaskBase plugin classes have alot of duplicate code too.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/lib/Drupal/Core/Menu/Plugin/Derivative/StaticLocalActionDeriver.phpundefined
@@ -0,0 +1,118 @@
+  public function getDerivativeDefinitions(array $base_plugin_definition) {
+    $parser = new Parser();
+
+    // @todo Replace with a generic YAML discovery solution when
+    // https://drupal.org/node/2050289 is complete.
+    foreach ($this->moduleHandler->getModuleList() as $module => $filename) {
+      $local_actions_file = DRUPAL_ROOT . '/' . dirname($filename) . '/' . $module . '.local_actions.yml';
+      if (file_exists($local_actions_file)) {
+        $local_actions = $parser->parse(file_get_contents($local_actions_file));
+
+        if (!empty($local_actions)) {
+          foreach ($local_actions as $name => $info) {
+            $this->derivatives[$name] = array(
+              'route_name' => isset($info['route_name']) ? $info['route_name'] : '',
+              'title' => isset($info['title']) ? $this->translationManager->translate($info['title']) : '',
+              'appears_on' => isset($info['appears_on']) ? $info['appears_on'] : array(),
+              'provider' => $module,
+            );
+
+            $this->derivatives[$name] += $base_plugin_definition;
+          }
+        }
+      }
+    }
+
+    return $this->derivatives;
+  }

Let's do this @todo now that #2050289: Add class to make yaml discovery reusable is in...

Edit: removed duplicated comment

damiankloip’s picture

Status: Needs work » Needs review
FileSize
2.59 KB
5.44 KB

Yep, Let's do that.

Status: Needs review » Needs work

The last submitted patch, 2050227-22.patch, failed testing.

alexpott’s picture

Missing a use statement for Drupal\Component\Discovery\YamlDiscovery

damiankloip’s picture

Status: Needs work » Needs review
FileSize
689 bytes
5.48 KB

Duh! thanks :)

dawehner’s picture

+++ b/core/lib/Drupal/Core/Menu/Plugin/Derivative/StaticLocalActionDeriver.phpundefined
@@ -0,0 +1,111 @@
+            'route_name' => isset($info['route_name']) ? $info['route_name'] : '',
+            'title' => isset($info['title']) ? $this->translationManager->translate($info['title']) : '',

I think it is pointless to have a local action without a route/title

damiankloip’s picture

Me and dawehner spoke briefly about this on IRC, It doesn't make sense if any of these keys aren't present. So let's just assume they are.

dawehner’s picture

+++ b/core/lib/Drupal/Core/Menu/Plugin/Derivative/StaticLocalActionDeriver.phpundefined
@@ -0,0 +1,111 @@
+  public function __construct($base_plugin_id, ModuleHandlerInterface $module_handler, TranslatorInterface $translation_manager) {
...
+            'title' => $this->translationManager->translate($info['title']),

Sorry but it seems to be that we should typehint TranslationManager, as the method we use (translate()) is just defined on that one.

tim.plunkett’s picture

damiankloip’s picture

So this patch should stay how it is in light of that? or we should change it now and that issue should change it back for us, depending on the outcome?

tim.plunkett’s picture

Just that whichever you do, there's a good chance you'll be wrong :)

dawehner’s picture

Hehe!

damiankloip’s picture

So, for now, we should just type hint TranslationManager.

damiankloip’s picture

We could also add this to the LocalActionTest.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Even I personally think it is wrong to provide two different basic discovery mechanisms for a plugin type the patch is fine. We are sort of in a state where an API break should better be avoided.

fubhy’s picture

I don't think it's wrong to provide different discovery mechanism. Technically that is always possible anyways. Developers are not stupid either. You can even use static to provide a dynamic discovery derivative definition, Uh yeah... Umh. Anyways, this is totally fine. We have different discovery mechanisms all over the place (for the same things). Think about route definitions (dynamic / yaml based). That's actually exactly the same except that dynamic is event driven, not annotation driven...

So, RTBC+1 (personally thinking that this is perfectly fine) :).

EclipseGc’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/lib/Drupal/Core/Menu/Plugin/Derivative/StaticLocalActionDeriver.phpundefined
@@ -0,0 +1,111 @@
+        foreach ($local_actions as $name => $info) {
+          $this->derivatives[$name] = array(
+            'route_name' => $info['route_name'],
+            'title' => $this->translationManager->translate($info['title']),
+            'appears_on' => $info['appears_on'],
+            'provider' => $module,
+          );
+
+          $this->derivatives[$name] += $base_plugin_definition;
+        }

This bugs me a bit. You've got the local_action info but you're throwing anything that doesn't match to your expected parameters away, and that's not really how this works. Usually you want to do something more like $this->derivatives[$name] = $info + $base_plugin_definition;

As an example, you're completely disregarding what the yml said with regard to provider. If you look at Core's Annotation discovery we only fill out provider if it's not already populated. Likewise, plugin definitions can have other stuff hung off them for unanticipated use cases, and you've completely eliminated the possibility for that in any instance other than drupal_alter usage.

That aside, I'm very ++ to this. I wouldn't worry about the "multiple ways to do something" as that's a side effect of allowing derivatives into your plugin type in the first place. Most derivatives utilize the UI to define plugins, but this is just as valid (in fact Layout plugins do exactly this already and have for a very long time now). More power to you.

Eclipse

damiankloip’s picture

Status: Needs work » Needs review
FileSize
1.17 KB
6.34 KB

That's a really good point, we don't know what other data people might might to hang off of this. Also, the provider is a good point which I totally overlooked :)

OK, new patch which should appease your concerns?

dawehner’s picture

@@ -93,14 +93,9 @@ public function getDerivativeDefinitions(array $base_plugin_definition) {
+          $info += array('title' => '', 'provider' => $module);
+          $info['title'] = $this->translationManager->translate($info['title']);

Mhh we should tell people if either the route_name or title is missing they are doing something wrong?

EclipseGc’s picture

re: 38

Yes that definitely solves my objections.

Eclipse

tim.plunkett’s picture

dawehner’s picture

Status: Needs review » Needs work

.

pwolanin’s picture

Status: Needs work » Needs review
FileSize
1.61 KB
6.63 KB

per dawahner - throws an exception if the definition is invalid.

damiankloip’s picture

+++ b/core/lib/Drupal/Core/Menu/Plugin/Derivative/StaticLocalActionDeriver.phpundefined
@@ -93,7 +95,10 @@ public function getDerivativeDefinitions(array $base_plugin_definition) {
+          if (!isset($info['title']) || empty($info['route_name']) || !is_array($info['appears_on'])) {

How is appears_on ever not going to be an array? as it's set as an array first.

Can't we do something a bit more informative, like this?

pwolanin’s picture

@damiankloip - well, even from the yaml it could be a string instead of an array?

Should we at least cast it to array?

We should supply it if missing.

damiankloip’s picture

Whatever. I don't mind.

There is no point in adding appears_on to the defaults as the the exception will catch it first.

pwolanin’s picture

oops, I think we should supply it?

Well, either way - if you want it to be empty, you can use [] in yaml

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

I really like the current version, as it is way easier to read than previous versions!

tim.plunkett’s picture

+1

damiankloip’s picture

Small thing, why the empty line between the use statements? iirc we haven't really been doing this.

pwolanin’s picture

@damiankloip - at least at one point we were doing it to separate symfony vs. Drupal classes, though not sure if it's been standardized.

EclipseGc’s picture

It's worth pointing out that the LocalAction Annotation class is already setting appears_on to an empty array, so you're going to get some sort of mismatch error if someone tries to pass a string in there based upon the derivative code that's adding the base plugin definition and the plugin definition from the yaml together. Just wanted to draw attention to that aspect. This code seems to have that covered as well, but no one had mentioned it. ++ing the rtbc.

Eclipse

damiankloip’s picture

FileSize
579 bytes
6.9 KB

Well, from my experience we've just been keeping them together/uniform, so we might as well.

Keeping rtbc as I'm only removing a line.

Status: Reviewed & tested by the community » Needs work
Issue tags: -MenuSystemRevamp

The last submitted patch, 2050227-53.patch, failed testing.

damiankloip’s picture

Status: Needs work » Needs review
Issue tags: +MenuSystemRevamp

#53: 2050227-53.patch queued for re-testing.

damiankloip’s picture

Status: Needs review » Reviewed & tested by the community
catch’s picture

Title: Add local action plugin deriver to use YAML discovery for static definitions » Change notice: Add local action plugin deriver to use YAML discovery for static definitions
Priority: Normal » Critical
Status: Reviewed & tested by the community » Active

Looks like a good change to me. Committed/pushed to 8.x, thanks!

webchick’s picture

Issue tags: +Needs change record

Just being the tag fairy, don't mind me. :D

dawehner’s picture

Status: Active » Needs review
pwolanin’s picture

Should be revised to use #2065571: Add YAML Plugin discovery?

damiankloip’s picture

Well, as discussed in the other issue, we need to get the OK to have that api change. Otherwise that's irrelevant.

Either way, I think we should start a new issue if/when we need to.

catch’s picture

catch’s picture

Issue summary: View changes

Updated issue summary.

star-szr’s picture

Title: Change notice: Add local action plugin deriver to use YAML discovery for static definitions » Add local action plugin deriver to use YAML discovery for static definitions
Priority: Major » Normal
Issue summary: View changes
Status: Needs review » Fixed
Issue tags: -Needs change record

Definitely time to close this one, the change notice at https://drupal.org/node/2007444 is looking good. Besides the revision by @dawehner last August we also have an extensive change by @pwolanin in October: https://drupal.org/node/2007444/revisions/view/2801357/2861533.

Status: Fixed » Closed (fixed)

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