Loading core/modules/node/src/Plugin/views/row/Rss.php +3 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,9 @@ public function render($row) { $build = \Drupal::entityTypeManager() ->getViewBuilder('node') ->view($node, $build_mode); // Add rss key to cache to differentiate this from other caches. $build['#cache']['keys'][] = 'view_rss'; unset($build['#theme']); if (!empty($node->rss_namespaces)) { Loading core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_article_feed.yml 0 → 100644 +207 −0 Original line number Diff line number Diff line langcode: en status: true dependencies: config: - core.entity_view_mode.node.teaser - node.type.article module: - node - user id: test_node_article_feed label: 'Test Node Article Feed' module: views description: '' tag: '' base_table: node_field_data base_field: nid display: default: display_plugin: default id: default display_title: Master position: 0 display_options: access: type: perm options: perm: 'access content' cache: type: tag options: { } query: type: views_query options: disable_sql_rewrite: false distinct: false replica: false query_comment: '' query_tags: { } exposed_form: type: basic options: submit_button: Apply reset_button: false reset_button_label: Reset exposed_sorts_label: 'Sort by' expose_sort_order: true sort_asc_label: Asc sort_desc_label: Desc pager: type: mini options: items_per_page: 10 offset: 0 id: 0 total_pages: null expose: items_per_page: false items_per_page_label: 'Items per page' items_per_page_options: '5, 10, 25, 50' items_per_page_options_all: false items_per_page_options_all_label: '- All -' offset: false offset_label: Offset tags: previous: ‹‹ next: ›› style: type: default options: grouping: { } row_class: '' default_row_class: true uses_fields: false row: type: fields options: inline: { } separator: '' hide_empty: false default_field_elements: true fields: title: id: title table: node_field_data field: title entity_type: node entity_field: title label: '' alter: alter_text: false make_link: false absolute: false trim: false word_boundary: false ellipsis: false strip_tags: false html: false hide_empty: false empty_zero: false settings: link_to_entity: true plugin_id: field relationship: none group_type: group admin_label: '' exclude: false element_type: '' element_class: '' element_label_type: '' element_label_class: '' element_label_colon: true element_wrapper_type: '' element_wrapper_class: '' element_default_classes: true empty: '' hide_alter_empty: true click_sort_column: value type: string group_column: value group_columns: { } group_rows: true delta_limit: 0 delta_offset: 0 delta_reversed: false delta_first_last: false multi_type: separator separator: ', ' field_api_classes: false filters: status: value: '1' table: node_field_data field: status plugin_id: boolean entity_type: node entity_field: status id: status expose: operator: '' operator_limit_selection: false operator_list: { } group: 1 type: id: type table: node_field_data field: type value: article: article entity_type: node entity_field: type plugin_id: bundle expose: operator_limit_selection: false operator_list: { } sorts: created: id: created table: node_field_data field: created order: DESC entity_type: node entity_field: created plugin_id: date relationship: none group_type: group admin_label: '' exposed: false expose: label: '' granularity: second header: { } footer: { } empty: { } relationships: { } arguments: { } display_extenders: { } cache_metadata: max-age: -1 contexts: - 'languages:language_content' - 'languages:language_interface' - url.query_args - 'user.node_grants:view' - user.permissions tags: { } feed_1: display_plugin: feed id: feed_1 display_title: 'Test Feed' position: 1 display_options: display_extenders: { } row: type: node_rss options: relationship: none view_mode: teaser path: test-node-article-feed display_description: '' cache_metadata: max-age: -1 contexts: - 'languages:language_content' - 'languages:language_interface' - 'user.node_grants:view' - user.permissions tags: { } core/modules/node/tests/src/Functional/NodeRssCacheTest.php 0 → 100644 +87 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\node\Functional; use Drupal\filter\Entity\FilterFormat; use Drupal\views\Tests\ViewTestData; /** * Ensures that RSS render cache doesn't interfere with other caches. * * Create a node, render that node as a teaser in the RSS feed, ensure that * the RSS teaser render doesn't contain tags from the default theme. * * @group node */ class NodeRssCacheTest extends NodeTestBase { /** * {@inheritdoc} */ protected static $modules = ['node_test', 'views', 'node_test_views']; /** * {@inheritdoc} */ public static $testViews = ['test_node_article_feed']; /** * {@inheritdoc} */ protected $defaultTheme = 'stark'; /** * {@inheritdoc} */ protected function setUp(): void { parent::setUp(); ViewTestData::createTestViews(static::class, ['node_test_views']); // Use bypass node access permission here, because the test class uses // hook_grants_alter() to deny access to everyone on node_access // queries. $user = $this->drupalCreateUser([ 'bypass node access', 'access content', 'create article content', ]); $this->drupalLogin($user); } /** * Ensure the RSS teaser render does not interfere with default theme cache. */ public function testNodeRssCacheContent() { // Only the plain_text text format is available by default, which escapes // all HTML. FilterFormat::create([ 'format' => 'full_html', 'name' => 'Full HTML', 'filters' => [], ])->save(); // Create the test node. $node = $this->drupalCreateNode([ 'type' => 'article', 'promote' => 1, 'title' => 'Article Test Title', 'body' => [ 'value' => '<p>Article test text.</p>', 'format' => 'full_html', ], ]); // Render the node in the RSS feed view as a teaser. $this->drupalGet('test-node-article-feed'); // Render the teaser normally. $viewBuilder = $this->container->get('entity_type.manager')->getViewBuilder('node'); $build = $viewBuilder->view($node, 'teaser'); $output = $this->container->get('renderer')->renderPlain($build); // Teaser must contain an "<article" tag from the stable9 theme. $this->assertStringContainsString('<article', (string) $output); } } Loading
core/modules/node/src/Plugin/views/row/Rss.php +3 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,9 @@ public function render($row) { $build = \Drupal::entityTypeManager() ->getViewBuilder('node') ->view($node, $build_mode); // Add rss key to cache to differentiate this from other caches. $build['#cache']['keys'][] = 'view_rss'; unset($build['#theme']); if (!empty($node->rss_namespaces)) { Loading
core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_article_feed.yml 0 → 100644 +207 −0 Original line number Diff line number Diff line langcode: en status: true dependencies: config: - core.entity_view_mode.node.teaser - node.type.article module: - node - user id: test_node_article_feed label: 'Test Node Article Feed' module: views description: '' tag: '' base_table: node_field_data base_field: nid display: default: display_plugin: default id: default display_title: Master position: 0 display_options: access: type: perm options: perm: 'access content' cache: type: tag options: { } query: type: views_query options: disable_sql_rewrite: false distinct: false replica: false query_comment: '' query_tags: { } exposed_form: type: basic options: submit_button: Apply reset_button: false reset_button_label: Reset exposed_sorts_label: 'Sort by' expose_sort_order: true sort_asc_label: Asc sort_desc_label: Desc pager: type: mini options: items_per_page: 10 offset: 0 id: 0 total_pages: null expose: items_per_page: false items_per_page_label: 'Items per page' items_per_page_options: '5, 10, 25, 50' items_per_page_options_all: false items_per_page_options_all_label: '- All -' offset: false offset_label: Offset tags: previous: ‹‹ next: ›› style: type: default options: grouping: { } row_class: '' default_row_class: true uses_fields: false row: type: fields options: inline: { } separator: '' hide_empty: false default_field_elements: true fields: title: id: title table: node_field_data field: title entity_type: node entity_field: title label: '' alter: alter_text: false make_link: false absolute: false trim: false word_boundary: false ellipsis: false strip_tags: false html: false hide_empty: false empty_zero: false settings: link_to_entity: true plugin_id: field relationship: none group_type: group admin_label: '' exclude: false element_type: '' element_class: '' element_label_type: '' element_label_class: '' element_label_colon: true element_wrapper_type: '' element_wrapper_class: '' element_default_classes: true empty: '' hide_alter_empty: true click_sort_column: value type: string group_column: value group_columns: { } group_rows: true delta_limit: 0 delta_offset: 0 delta_reversed: false delta_first_last: false multi_type: separator separator: ', ' field_api_classes: false filters: status: value: '1' table: node_field_data field: status plugin_id: boolean entity_type: node entity_field: status id: status expose: operator: '' operator_limit_selection: false operator_list: { } group: 1 type: id: type table: node_field_data field: type value: article: article entity_type: node entity_field: type plugin_id: bundle expose: operator_limit_selection: false operator_list: { } sorts: created: id: created table: node_field_data field: created order: DESC entity_type: node entity_field: created plugin_id: date relationship: none group_type: group admin_label: '' exposed: false expose: label: '' granularity: second header: { } footer: { } empty: { } relationships: { } arguments: { } display_extenders: { } cache_metadata: max-age: -1 contexts: - 'languages:language_content' - 'languages:language_interface' - url.query_args - 'user.node_grants:view' - user.permissions tags: { } feed_1: display_plugin: feed id: feed_1 display_title: 'Test Feed' position: 1 display_options: display_extenders: { } row: type: node_rss options: relationship: none view_mode: teaser path: test-node-article-feed display_description: '' cache_metadata: max-age: -1 contexts: - 'languages:language_content' - 'languages:language_interface' - 'user.node_grants:view' - user.permissions tags: { }
core/modules/node/tests/src/Functional/NodeRssCacheTest.php 0 → 100644 +87 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\node\Functional; use Drupal\filter\Entity\FilterFormat; use Drupal\views\Tests\ViewTestData; /** * Ensures that RSS render cache doesn't interfere with other caches. * * Create a node, render that node as a teaser in the RSS feed, ensure that * the RSS teaser render doesn't contain tags from the default theme. * * @group node */ class NodeRssCacheTest extends NodeTestBase { /** * {@inheritdoc} */ protected static $modules = ['node_test', 'views', 'node_test_views']; /** * {@inheritdoc} */ public static $testViews = ['test_node_article_feed']; /** * {@inheritdoc} */ protected $defaultTheme = 'stark'; /** * {@inheritdoc} */ protected function setUp(): void { parent::setUp(); ViewTestData::createTestViews(static::class, ['node_test_views']); // Use bypass node access permission here, because the test class uses // hook_grants_alter() to deny access to everyone on node_access // queries. $user = $this->drupalCreateUser([ 'bypass node access', 'access content', 'create article content', ]); $this->drupalLogin($user); } /** * Ensure the RSS teaser render does not interfere with default theme cache. */ public function testNodeRssCacheContent() { // Only the plain_text text format is available by default, which escapes // all HTML. FilterFormat::create([ 'format' => 'full_html', 'name' => 'Full HTML', 'filters' => [], ])->save(); // Create the test node. $node = $this->drupalCreateNode([ 'type' => 'article', 'promote' => 1, 'title' => 'Article Test Title', 'body' => [ 'value' => '<p>Article test text.</p>', 'format' => 'full_html', ], ]); // Render the node in the RSS feed view as a teaser. $this->drupalGet('test-node-article-feed'); // Render the teaser normally. $viewBuilder = $this->container->get('entity_type.manager')->getViewBuilder('node'); $build = $viewBuilder->view($node, 'teaser'); $output = $this->container->get('renderer')->renderPlain($build); // Teaser must contain an "<article" tag from the stable9 theme. $this->assertStringContainsString('<article', (string) $output); } }