Problem

When views are added as blocks the contextual link doesn't work as expected. The block outputs two contextual links with the same ID which causes some issues with the way that Backbone binds and creates the event handlers. Reviewing the event handlers in the inspect you can see that the element has 2 click handlers which triggers openToggle twice (once opening and once closing) which causes the contextual button to never show the menu.

Only local images are allowed.

Steps to reproduce

- Create a view as a block
- Add the block to the page (tested with Panels and with the default Block UI)
- View source for the page and you will see the duplicated contextual block

Proposed resolution

  • Move adding the contextual links to DisplayPluginBase
  • Remove adding the contextual links to the View element and the view block
  • Update contextual.js to filter the list of IDs so that it doesn't try to bind to the same element (ids should be unique on the page)

Remaining tasks

Testing and review the proposed fix.

Debugging notes

While debugging this I found

  • views adds contextual links in two places; \Drupal\views\Plugin\Block\ViewBlockBase and \Drupal\views\Element\View
  • Disabling the contextual link for the view block removes both instances of the link (on the block and the view)
  • Tracking a static for a given contextual ID in the views_add_contextual_links function didn't prevent it from duplicating
  • Seems to not be related to theme implementations (tried with Cog, Bootstrap, Bartik and all had the same issue)
  • Tested with both Block UI and Panels
  • Exposed form blocks still display contextual link after the proposed fix is applied

Issue fork drupal-2884801

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

steveworley created an issue. See original summary.

steveworley’s picture

I came across the bug while testing views translations as I wanted to translate some of the static elements (footers). Apologies if there is another issue opened where this would be better to track against. There are a few issues that are discussing contextual links and some issues that people are having with those but this seemed a little different.

steveworley’s picture

StatusFileSize
new6.11 KB
lendude’s picture

Status: Active » Needs work
Issue tags: +Needs tests

@steveworley thanks for the extensive report and patch! Next time, if you upload a patch, please select a 'test with' version and put the issue status on 'needs review' to make sure it is tested by the testbot. Really curious to see what this breaks.

Some initial points:

  1. +++ b/core/modules/contextual/js/contextual.js
    @@ -147,4 +150,4 @@
    -})(jQuery, Drupal, drupalSettings, _, Backbone, window.JSON, window.sessionStorage);
    \ No newline at end of file
    +})(jQuery, Drupal, drupalSettings, _, Backbone, window.JSON, window.sessionStorage);
    

    Unrelated change, lets leave it out, for easier reviewing

  2. +++ b/core/modules/views/src/Plugin/Block/ViewsBlockBase.php
    @@ -186,24 +186,10 @@ public function blockSubmit($form, FormStateInterface $form_state) {
    +   * @deprecated Contextual links applied via DisplayPluginBase.
        */
       protected function addContextualLinks(&$output, $block_type = 'block') {
    

    Deprecating it is fine, but we can't remove the contents of this method, other modules might rely on it.

  3. +++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
    @@ -2360,6 +2363,9 @@ public function buildRenderable(array $args = [], $cache = TRUE) {
    +    views_add_contextual_links($this->view->element, "block", $this->display['id']);
    

    This can't default to 'block' in the DisplayPluginBase right? That would mess with other displays.

Also, this needs tests. Not sure if there is any javascript test coverage for contextual filters at the moment (actually pretty sure there isn't), but we need some.

manuel garcia’s picture

Status: Needs work » Needs review
StatusFileSize
new2.15 KB
new5.33 KB
index 558ea10..87a7ad7 100644
--- a/core/modules/contextual/js/contextual.es6.js

--- a/core/modules/contextual/js/contextual.es6.js
+++ b/core/modules/contextual/js/contextual.es6.js

+++ b/core/modules/contextual/js/contextual.es6.js
@@ -160,6 +160,9 @@

@@ -160,6 +160,9 @@
         ids.push($(this).attr('data-contextual-id'));
       });
 
+      // Remove duplicates from the IDs array.
+      ids = _.uniq(ids);
+
       // Update all contextual links placeholders whose HTML is cached.
       var uncachedIDs = _.filter(ids, function initIfCached(contextualID) {
         var html = storage.getItem('Drupal.contextual.' + contextualID);
diff --git a/core/modules/contextual/js/contextual.js b/core/modules/contextual/js/contextual.js

diff --git a/core/modules/contextual/js/contextual.js b/core/modules/contextual/js/contextual.js
index 9093d97..c225b15 100644

index 9093d97..c225b15 100644
--- a/core/modules/contextual/js/contextual.js

--- a/core/modules/contextual/js/contextual.js
+++ b/core/modules/contextual/js/contextual.js

+++ b/core/modules/contextual/js/contextual.js
@@ -101,6 +101,9 @@

@@ -101,6 +101,9 @@
         ids.push($(this).attr('data-contextual-id'));
       });
 
+      // Remove duplicates from the IDs array.
+      ids = _.uniq(ids);
+

We now need to "compile" es6 js files like this (inside core/ dir):
yarn run build:js -- --file modules/contextual/js/contextual.es6.js
Doing that in this patch.
#4.1 is automatically done by the compiling action.
Fixing #4.2 as well.

What #4.3 talks about brings up the issue of how views_add_contextual_links() is built... that parameter seems like it is very special, it can be on of three hardcoded values , or:

 * If you are rendering a view and its contextual links in another location,
 *   you can pass in a different value for this parameter. However, you will
 *   also need to set 'contextual_links_locations' in your plugin annotation to
 *   indicate which view displays support having their contextual links
 *   rendered in the location you have defined.

So this isn't as straight forward as it may seem, so I'm not entirely sure about the proposed solution.
How do we know what to pass to views_add_contextual_links from DisplayPluginBase::buildRenderable() ?

manuel garcia’s picture

StatusFileSize
new1.74 KB

Appologies, the interdiff came out wrong. Here is the good one.

manuel garcia’s picture

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Anonymous’s picture

We also discovered the problem of binding in #2891603: Contextual links can't handle multiple occurrences of the same contextual links (again). It is a pity that we did not notice each other at once. As a result, there was a duplication. You have a good description of the binding problem, we have a test and a simpler solution. Let's cooperate! 🤝

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

psf_’s picture

Issue summary: View changes
psf_’s picture

I updated the Manuel Garcia's patch to 8.5.x, but it need tests too.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

ranjith_kumar_k_u’s picture

StatusFileSize
new4.89 KB

Re-rolled for 9.2

kapilv’s picture

Assigned: Unassigned » kapilv
kapilv’s picture

Assigned: kapilv » Unassigned

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

abarrio’s picture

Applid patch from #18 on Drupal 9.3 and is working perfect.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new144 bytes

The Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

mortona2k made their first commit to this issue’s fork.

mortona2k’s picture

Issue summary: View changes
StatusFileSize
new56.34 KB

I created an issue fork and added the patch.

I am testing by placing the recent content block via block UI.

What I'm seeing is duplicate contextual links for the block and for the view itself.

The only duplicated link is edit view, which is the only one on the view links.

I have any issues with opening the contextual links when the block title is visible.

If the block title is hidden, the view links overlap the block links.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

mortona2k’s picture

The MR is not working on D11.

Need to remove use of backbone code, removed in 11.2