Issue #2823914 by danflanagan8: Render caching in DisplayPluginInterface::buildRenderable is broken when arguments are provided

merge-requests/593/head
Lee Rowlands 2021-04-26 18:53:30 +10:00
parent f0f758a4bc
commit 10fc602385
No known key found for this signature in database
GPG Key ID: 2B829A3DF9204DC4
5 changed files with 73 additions and 3 deletions

View File

@ -2410,6 +2410,12 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte
// Places like \Drupal\views\ViewExecutable::setCurrentPage() set up an
// additional cache context.
$this->view->element['#cache']['keys'] = array_merge(['views', 'display', $this->view->element['#name'], $this->view->element['#display_id']], $this->view->element['#cache']['keys']);
// Add arguments to the cache key.
if ($args) {
$this->view->element['#cache']['keys'][] = 'args';
$this->view->element['#cache']['keys'][] = implode(',', $args);
}
}
else {
// Remove the cache keys, to ensure render caching is not triggered. We

View File

@ -0,0 +1,37 @@
<?php
namespace Drupal\views_test_render_cache\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\views\Views;
/**
* Provides route responses.
*/
class ViewsTestRenderCacheController extends ControllerBase {
/**
* Returns the same block rendered twice with different arguments.
*
* @var string $view_id
* The view id.
* @var string $display_id
* The display id of display to be rendered twice.
* @var string $args_1
* Comma-separated args to use in the first rendering.
* @var string $args_2
* Comma-separated args to use in the second rendering.
*
* @return array
* A renderable array.
*/
public function double(string $view_id, string $display_id, string $args_1, string $args_2) {
$build = [];
$view = Views::getView($view_id);
$build[] = $view->buildRenderable($display_id, explode(",", $args_1));
$view = Views::getView($view_id);
$build[] = $view->buildRenderable($display_id, explode(",", $args_2));
return $build;
}
}

View File

@ -0,0 +1,7 @@
name: 'Views Test Render Cache'
type: module
description: 'Provides routes for testing render cache.'
package: Testing
version: VERSION
dependencies:
- drupal:views

View File

@ -0,0 +1,7 @@
views_test_render_cache.blocks:
path: '/views_test_render_cache/{view_id}/{display_id}/{args_1}/{args_2}'
defaults:
_controller: '\Drupal\views_test_render_cache\Controller\ViewsTestRenderCacheController::double'
_title: 'Test!'
requirements:
_access: 'TRUE'

View File

@ -14,7 +14,7 @@ class RenderCacheWebTest extends ViewTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = ['node', 'block'];
protected static $modules = ['node', 'block', 'views_test_render_cache'];
/**
* {@inheritdoc}
@ -53,14 +53,13 @@ class RenderCacheWebTest extends ViewTestBase {
]);
$node->save();
$this->nodes[] = $node;
$this->placeBlock('views_block:node_id_argument-block_1', ['region' => 'header']);
}
/**
* Tests rendering caching of a views block with arguments.
*/
public function testEmptyView() {
$this->placeBlock('views_block:node_id_argument-block_1', ['region' => 'header']);
$this->drupalGet('<front>');
$this->assertEqual([], $this->cssSelect('div.region-header div.views-field-title'));
@ -77,4 +76,18 @@ class RenderCacheWebTest extends ViewTestBase {
$this->assertEqual('test title 1', $result);
}
/**
* Tests render caching for display rendered with different args on same page.
*/
public function testRepeatedDisplay() {
$this->drupalGet("views_test_render_cache/node_id_argument/block_1/{$this->nodes[0]->id()}/{$this->nodes[1]->id()}");
// Confirm there are two displays.
$displays = $this->cssSelect('.views-element-container .view-id-node_id_argument.view-display-id-block_1');
$this->assertCount(2, $displays, 'There are two displays');
// First display should only have test title 1.
$this->assertSame($this->nodes[0]->getTitle(), $displays[0]->getText());
// Second display should only have test title 2.
$this->assertSame($this->nodes[1]->getTitle(), $displays[1]->getText());
}
}