Problem/Motivation

Entity operations for terms are hardcoded in taxonomy terms's overview page; add or alter operations is impossible.

Proposed resolution

Introduce a taxonomy term list builder that provides the operations and invokes all existing hooks for other modules to alter the operations or provide custom ones. See #3 and #4 for why we need a list builder.

Remaining tasks

Make a patch.

User interface changes

none.

API changes

none.

Beta phase evaluation

Reference: https://www.drupal.org/core/beta-changes
Issue category Bug
Issue priority Normal, because no data loss or seriously broken features.
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

willzyx’s picture

Xano’s picture

FileSize
3.81 KB

We use a new approach for this in Drupal 8. All entity operations should be provided by the entity type's list builder (which primarily builds entity listings). The list builders allow entity types to provide their own operations, but also invoke the hooks that are necessary for other modules to provide additional operations. The prime example of that in core are probably the content and config translation modules.

Because term listings are more complex–they cannot be listed all at once, but only per vocabulary–we can only use the term list builder for providing operations. We've done this in core once before (I cannot remember where exactly right now).

willzyx’s picture

I cannot find another point in which the list builder is used in this way in core.. and doing so dont we lose the destination?

Xano’s picture

FileSize
2.19 KB
5.49 KB

It's been done before somewhere in a core issue (I remember discussing it with @sun). The reason is that operations handlers could no longer be added to core after code freeze. This is why list builders have become responsible for providing operations links, even though they cannot always provide lists too.

This patch adds destinations.

willzyx’s picture

call parent::__construct() instead of set manually the member variables and change ::getOperations to ::getDefaultOperations.
Furthemore in ::render() \LogicException is more appropriate, isn't it?

Xano’s picture

Status: Needs review » Needs work

call parent::__construct() instead of set manually the member variables and change ::getOperations to ::getDefaultOperations.

Duh... Thanks!

Furthemore in ::render() \LogicException is more appropriate, isn't it?

It's all potatoes potatoes to me. I looked it up and \LogicException makes sense indeed.

+++ b/core/modules/taxonomy/src/TermListBuilder.php
@@ -31,36 +31,37 @@
-  public function getOperations(EntityInterface $entity) {
-    $operations = parent::getOperations($entity);
-    foreach ($operations as &$operation) {
-      $operation['query']['destination'] = $this->redirectDestination->get();
+  public function getDefaultOperations(EntityInterface $entity) {
+    $operations = parent::getDefaultOperations($entity);
+
+    $destination = $this->redirectDestination->getAsArray();
+    foreach ($operations as $key => $operation) {
+      $operations[$key]['query'] = $destination;

This change is actually a regression, as it would override any existing GET parameters and we don't want that.

willzyx’s picture

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

looking at EntityListBuilder::getDefaultOperations() this should not be a problem. however..

Xano’s picture

Thanks!

It's unlikely, but the way your patch from #7 does it, is better practice. Basically: don't touch anything you don't have to.

Xano’s picture

Thanks!

It's unlikely, but the way your patch from #7 does it, is better practice. Basically: don't touch anything you don't have to.

willzyx’s picture

I think we should create, in a similar manner, a patch for shortcuts (links list page)

miro_dietiker’s picture

We tried to implement hook_entity_operation_alter() for all entity types in collect contrib and it was not possible to alter tag operations. See #2491307: Add "Capture" operation to all content entities
Works like a charm after applying this patch.

andypost’s picture

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

Any reason to introduce non-usable list bulder?
Suppose proper fix is to convert OverviewTerms to list builder

+++ b/core/modules/taxonomy/src/Entity/Term.php
@@ -30,6 +30,7 @@
+ *     "list_builder" = "Drupal\taxonomy\TermListBuilder",

+++ b/core/modules/taxonomy/src/Form/OverviewTerms.php
@@ -265,28 +272,9 @@ public function buildForm(array $form, FormStateInterface $form_state, Vocabular
       $form['terms'][$key]['operations'] = array(
         '#type' => 'operations',
-        '#links' => $operations,
+        '#links' => $this->termListBuilder->getOperations($term),

+++ b/core/modules/taxonomy/src/TermListBuilder.php
@@ -0,0 +1,77 @@
+  public function render() {
+    throw new \LogicException('This list builder can only provide operations. It does not build lists.');

incredible hack...

Xano’s picture

Issue summary: View changes
Status: Needs work » Needs review
Issue tags: -Needs issue summary update

See #3 and #4 for why this is done in such a 'hacky' way. In 2014 the decision was made that because of code freeze we could no longer add new entity type handlers. The entire page cannot be converted to a list builder easily or at all, because the page only displays terms for a specific vocabulary, whereas list builders were designed to display all entities of a specified type.

miro_dietiker’s picture

Looks much RTBC to me. (edited) Except: There is no documentation at all that explains why the TermListBuilder is limited to operations only.

Xano’s picture

Looks much RTBC to me. There is documentation at all that explains why the TermListBuilder is limited to operations only.

Does this mean there is or is not enough documentation?

If there is, do you see any other objections to an RTBC?

Status: Needs review » Needs work

The last submitted patch, 7: d8-hardcoded-terms-operations-2469567-7.patch, failed testing.

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 7: d8-hardcoded-terms-operations-2469567-7.patch, failed testing.

Status: Needs work » Needs review
miro_dietiker’s picture

I'm not used to documentation verbosity in core.

+++ b/core/modules/taxonomy/src/TermListBuilder.php
@@ -0,0 +1,77 @@
+ * Provides a taxonomy term list builder.
...
+    throw new \LogicException('This list builder can only provide operations. It does not build lists.');

There is zero explanation on why. I would have expected to see some comment similar to your words above:

The entire page cannot be converted to a list builder easily or at all, because the page only displays terms for a specific vocabulary, whereas list builders were designed to display all entities of a specified type.

Xano’s picture

Status: Needs review » Needs work

The technical reason is that we crammed two separate features (list building and operations) in the same interface (ListBuilderInterface) and we shouldn't have. There are numerous reasons why classes wouldn't want to provide lists, but do provide operations.

In practice, the only reason I have seen so far (IIRC) is that we use alternative listing methods. I'm not sure we should explain this in the exception message, as the choice to use these alternative methods lies with the application (the entity type definition) and not with the list builder itself.

However, based on that reasoning, we should perhaps allow lists to be made using this list builder in case someone wants a list of terms across all vocabularies. It would also mean the class complies with the interface and there are no WTFs about application-level decisions.

Thanks for pointing out we can and should improve documentation!

Arla’s picture

Why is the destination param expected for term operations but not for operations of other entity types? Should we consider adding destination param to (some) operations in EntityListBuilder?

gapple’s picture

Ran into a similar issue with menu links, so created #2684577: Entity operations for menu links are hardcoded in edit menu form with some changes based on this issue.

miro_dietiker’s picture

Version: 8.0.x-dev » 8.2.x-dev

Hm i guess it would be 8.x-2.x target meanwhile?

gapple’s picture

Re-roll for 8.2.x

Status: Needs review » Needs work

The last submitted patch, 28: d8-hardcoded-terms-operations-2469567-28.patch, failed testing.

Arla’s picture

Did a little bit of digging to answer #25, and found that both term and node operations have been including the destination for a long time. I guess there's no point in trying to change that in this issue.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

effulgentsia’s picture

I queued a retest of #28 (on 8.3.x) to see if anything's changed in 6 months.

effulgentsia’s picture

Cool. Same two failures. Anyone here able to debug them?

mohit_aghera’s picture

@effulgentsia i am on it.

mohit_aghera’s picture

andypost’s picture

+++ b/core/modules/forum/src/Form/Overview.php
@@ -61,12 +61,15 @@ public function buildForm(array $form, FormStateInterface $form_state) {
-        else {
+        elseif (!empty($route_parameters)) {
           $form['terms'][$key]['operations']['#links']['edit']['title'] = $this->t('edit forum');

this change is wrong! edit forum always have params!

mohit_aghera’s picture

@andypost i tried to replicate it.
However exception is at the same line. [Notice] Line 64 of core/modules/forum/src/Form/Overview.php
Tried to reproduce by running test case locally as well.

Can there be anything that is internally calling `Overview.php` of forum module ?

Berdir’s picture

  1. +++ b/core/modules/taxonomy/src/TermListBuilder.php
    @@ -0,0 +1,77 @@
    +   * {@inheritdoc}
    +   */
    +  public function getDefaultOperations(EntityInterface $entity) {
    +    $operations = parent::getDefaultOperations($entity);
    +
    +    $destination = $this->redirectDestination->get();
    +    foreach ($operations as $key => $operation) {
    +      $operations[$key]['query']['destination'] = $destination;
    +    }
    +
    +    return $operations;
    +  }
    +
    

    #2767857: Add destination to edit, delete, enable, disable links in entity list builders does this in a generic way, then we wouldn't need this anymore.

  2. +++ b/core/modules/taxonomy/src/TermListBuilder.php
    @@ -0,0 +1,77 @@
    +   * {@inheritdoc}
    +   */
    +  public function render() {
    +    throw new \LogicException('This list builder can only provide operations. It does not build lists.');
    +  }
    +
    

    not sure why we need to do this.

Berdir’s picture

Not sure if/why that is needed with the forum operations but what about moving that to hook_entity_operations_alter() and out of the custom controller?

effulgentsia’s picture

#2767857: Add a list builder with a label and destination query parameters in operation links does this in a generic way, then we wouldn't need this anymore.

But that issue sets the destination to the 'collection' link template. Which wouldn't work for taxonomy terms, since they don't have such a template, and if we wanted to add such a template, it would need to have the {taxonomy_vocabulary} parameter. I guess we could do that by adding a Term::urlRouteParameters() override?

Berdir’s picture

Yeah, but as I commented there, I think that is wrong anyway and we should use the redirect destination API which defaults to the current page. See also #2838968: BlockContentListBuilder should use RedirectDestinationTrait instead of hardcoding the collection link template, any view that displays operation links would have the same problem as term.

effulgentsia’s picture

claudiu.cristea’s picture

This is a bug and should go to 8.2.x. I rerolled #7, that was the last good.

@Berdir,

#2767857: Add a list builder with a label and destination query parameters in operation links does this in a generic way, then we wouldn't need this anymore.

That is a 8.3.x issue and that should account this fix if this will go first. Or we fix here if that goes first.

Removed render() hack.

Status: Needs review » Needs work

The last submitted patch, 43: 2469567-43.patch, failed testing.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

andypost’s picture

farald’s picture

Re-roll against 8.3.x.
Tests are probably still failing though.

miro_dietiker’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 47: 2469567-47.patch, failed testing.

Berdir’s picture

Status: Needs work » Closed (duplicate)

I posted a detailed overview of all related issues that we have around this topic in #1848686-179: Add a dedicated permission to access the term overview page (without 'administer taxonomy' permission) (#179 if the link does not work).

As suggested there, I'm closing this issue as a duplicate of that issue as that also has to solve this problem.

I'll try to update that other issue and possibly incorporate the approach that this issue uses with the list builder.

josmera01’s picture

Add the patch for the version Drupal 8.3