Quantcast
Channel: Issues for Drupal core
Viewing all articles
Browse latest Browse all 291720

Views cache contexts are lost (and thus do not bubble) when rendering a view's block display.

$
0
0

Problem/Motivation

The 'url' cache context for views block displays is sometimes missing when it shouldn't be because \Drupal\views\Plugin\views\display\DisplayPluginBase::buildRenderable() only bubbles the context cachablity metadata when it has been asked to create a render cache for the output.

This can lead to problems where empty view blocks get cached.

Steps to reproduce

This started out as a long adventure into why empty view blocks get cached, so here are some steps to reproduce:

Setup

(note that I exported and attached my test site's configuration in #2— this could save you time)

  1. Install Drupal 8.0.x using the minimal install profile.
  2. Enable field_ui, views, views_ui modules.
  3. Go to /admin/structure/types/add, add a newcontent type:
    • Name = Test
    • Publishing options:
      • Promoted to front page = FALSE
    • (leave the rest of the fields at their default value)
  4. Go to admin/structure/types/manage/test/display and disable the body field (i.e.: set it's Format = - Hidden -).
  5. Go to /node/add/test, add a first new piece of content:
    • Title = First test
    • Body = Lorem ipsum
    • (leave the rest of the fields at their default value)
  6. Go to /node/add/test, add a second new piece of content:
    • Title = Second test
    • Body = Dolor sit
    • (leave the rest of the fields at their default value)
  7. Go to /admin/structure/views/add, add a new view:
    • View basic information:
      • View name = "Tests"
      • (leave the rest of the fields at their defaultvalue)
    • View settings:
      • Show Content of type Test sorted by Unsorted
    • Page settings
      • (leave the rest of the fields at their default value)
    • Block settings
      • Create a block = TRUE
      • Block title = Tests
      • Block display settings:
        • Display format: Unformatted list of Fields
    • (leave the rest of the fields at their default value)
    • Click Save and edit
    • Under Fields, remove the default Content: Title field, and add a Content: Body field (the default settings are fine).
    • Under Advanced, add a Contextual Filter. Select Node ID, and click
      Apply (all displays):
      • When the filter value is NOT available:
        • Default actions: Provide default value:
          • Type = Content ID from URL
      • (leave the rest of the fields at their default value)
    • Save the view.
  8. Go to admin/structure/block
    • In Footer, click Place block. Find the Tests block from the category Lists (Views), and click Place block. Save using the default settings.
    • Click Save blocks
Test 1
  1. Clear all caches: drush -y cr
  2. Go to /node.
  3. Go to /node/1.
    • Expcected behaviour: A block is displayed in the footer with the contents of the body field ("Lorem ipsum").
    • Actual behaviour: No block is displayed.
  4. Go to /node/2.
    • Expcected behaviour: A block is displayed in the footer with the contents of the body field ("Dolor sit").
    • Actual behaviour: No block is displayed.
Test 2
  1. Clear all caches: drush -y cr
  2. Go to /node/1. Note the block is displayed in the footer with the contents of the body field ("Lorem ipsum").
  3. Go to /node/2. Note the block is displayed in the footer with the contents of the body field ("Dolor sit").
Test 3
  1. In settings[.local].php, disable the render cache by adding the following lines:
    $settings['container_yamls'][] = DRUPAL_ROOT . '/sites/development.services.yml';
    $settings['cache']['bins']['render'] = 'cache.backend.null';
  2. Clear all caches: drush -y cr
  3. Go to /node.
  4. Go to /node/1. Note the block is displayed in the footer with the contents of the body field ("Lorem ipsum").
  5. Go to /node/2. Note the block is displayed in the footer with the contents of the body field ("Dolor sit").
Test 4
  1. Remove the lines from settings[.local].php you added in step 3, if applicable. Re-run Test 1 to confirm the bug occurs.
  2. Apply the following patch:
    diff --git a/core/modules/views/src/Plugin/Block/ViewsBlock.php b/core/modules/views/src/Plugin/Block/ViewsBlock.php
    index 20dbace..530d9e3 100644
    --- a/core/modules/views/src/Plugin/Block/ViewsBlock.php
    +++ b/core/modules/views/src/Plugin/Block/ViewsBlock.php
    @@ -127,4 +127,15 @@ public function getMachineNameSuggestion() {
         return 'views_block__' . $this->view->storage->id() . '_' . $this->view->current_display;
       }

    +  /**
    +   * {@inheritdoc}
    +   */
    +  public function getCacheContexts() {
    +    $contexts = parent::getCacheContexts();
    +
    +    $contexts[] = 'url';
    +
    +    return $contexts;
    +  }
    +
    }
  3. Clear all caches: drush -y cr
  4. Go to /node.
  5. Go to /node/1. Note the block is displayed in the footer with the contents of the body field ("Lorem ipsum").
  6. Go to /node/2. Note the block is displayed in the footer with the contents of the body field ("Dolor sit").
  7. Proposed resolution

    Always pass the cachablity metadata; but if we're not supposed to cache the view's output, remove the cache tags, leaving the rest of the metadata to bubble.

    Remaining tasks

    1. Figure out what's causing empty blocks to be cached.
    2. Write a patch
    3. Review and feedback
    4. RTBC.
    5. Commit.

    User interface changes

    None.

    API changes

    None.

    Data model changes

    None.


Viewing all articles
Browse latest Browse all 291720

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>