From eaa0c629f067ce9fefa8ec0c947539519484a3cc Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Wed, 16 Apr 2025 09:40:58 +0200
Subject: [PATCH 01/23] feat: apply patch #27 with some small updates

---
 .../comment/src/Plugin/views/row/Rss.php      | 10 ++--
 .../tests/src/Unit/ConfigNamesMapperTest.php  |  5 --
 .../modules/node/src/Plugin/views/row/Rss.php | 12 ++---
 .../system/config/install/system.rss.yml      |  2 -
 .../system/config/schema/system.schema.yml    | 12 -----
 core/modules/system/migrations/system_rss.yml | 16 -------
 core/modules/system/src/Form/RssFeedsForm.php | 48 -------------------
 .../system/system.config_translation.yml      |  6 ---
 core/modules/system/system.links.menu.yml     |  5 --
 core/modules/system/system.links.task.yml     |  5 --
 core/modules/system/system.post_update.php    |  7 +++
 core/modules/system/system.routing.yml        |  8 ----
 .../Functional/Update/SystemRssDeleteTest.php | 37 ++++++++++++++
 .../d6/MigrateSystemConfigurationTest.php     |  6 ---
 .../d7/MigrateSystemConfigurationTest.php     |  6 ---
 .../src/Plugin/views/row/RssPluginBase.php    | 15 +++++-
 16 files changed, 64 insertions(+), 136 deletions(-)
 delete mode 100644 core/modules/system/config/install/system.rss.yml
 delete mode 100644 core/modules/system/migrations/system_rss.yml
 delete mode 100644 core/modules/system/src/Form/RssFeedsForm.php
 create mode 100644 core/modules/system/tests/src/Functional/Update/SystemRssDeleteTest.php

diff --git a/core/modules/comment/src/Plugin/views/row/Rss.php b/core/modules/comment/src/Plugin/views/row/Rss.php
index f15b031e8c38..78a8d098edc3 100644
--- a/core/modules/comment/src/Plugin/views/row/Rss.php
+++ b/core/modules/comment/src/Plugin/views/row/Rss.php
@@ -66,8 +66,7 @@ public function preRender($result) {
    */
   public function buildOptionsForm_summary_options() {
     $options = parent::buildOptionsForm_summary_options();
-    $options['title'] = $this->t('Title only');
-    $options['default'] = $this->t('Use site default RSS settings');
+    $options[$this::TITLE_VIEW_MODE] = $this->t('Title only');
     return $options;
   }
 
@@ -83,9 +82,6 @@ public function render($row) {
     }
 
     $view_mode = $this->options['view_mode'];
-    if ($view_mode == 'default') {
-      $view_mode = \Drupal::config('system.rss')->get('items.view_mode');
-    }
 
     // Load the specified comment and its associated node:
     /** @var \Drupal\comment\CommentInterface $comment */
@@ -113,7 +109,7 @@ public function render($row) {
 
     // The comment gets built and modules add to or modify
     // $comment->rss_elements and $comment->rss_namespaces.
-    $build = $this->entityTypeManager->getViewBuilder('comment')->view($comment, 'rss');
+    $build = $this->entityTypeManager->getViewBuilder('comment')->view($comment, $view_mode);
     unset($build['#theme']);
 
     if (!empty($comment->rss_namespaces)) {
@@ -121,7 +117,7 @@ public function render($row) {
     }
 
     $item = new \stdClass();
-    if ($view_mode != 'title') {
+    if ($view_mode != $this::TITLE_VIEW_MODE) {
       // We render comment contents.
       $item->description = $build;
     }
diff --git a/core/modules/config_translation/tests/src/Unit/ConfigNamesMapperTest.php b/core/modules/config_translation/tests/src/Unit/ConfigNamesMapperTest.php
index 5bbe2b9a3098..cc17c6304e60 100644
--- a/core/modules/config_translation/tests/src/Unit/ConfigNamesMapperTest.php
+++ b/core/modules/config_translation/tests/src/Unit/ConfigNamesMapperTest.php
@@ -470,11 +470,6 @@ public function testGetConfigData(): void {
         'enabled' => FALSE,
         'message' => '@site is currently under maintenance.',
       ],
-      'system.rss' => [
-        'items' => [
-          'view_mode' => 'rss',
-        ],
-      ],
     ];
 
     $this->configNamesMapper->setConfigNames(array_keys($configs));
diff --git a/core/modules/node/src/Plugin/views/row/Rss.php b/core/modules/node/src/Plugin/views/row/Rss.php
index 56549f01d124..6e33e522743d 100644
--- a/core/modules/node/src/Plugin/views/row/Rss.php
+++ b/core/modules/node/src/Plugin/views/row/Rss.php
@@ -51,8 +51,7 @@ class Rss extends RssPluginBase {
    */
   public function buildOptionsForm_summary_options() {
     $options = parent::buildOptionsForm_summary_options();
-    $options['title'] = $this->t('Title only');
-    $options['default'] = $this->t('Use site default RSS settings');
+    $options[$this::TITLE_VIEW_MODE] = $this->t('Title only');
     return $options;
   }
 
@@ -89,9 +88,6 @@ public function render($row) {
     }
 
     $display_mode = $this->options['view_mode'];
-    if ($display_mode == 'default') {
-      $display_mode = \Drupal::config('system.rss')->get('items.view_mode');
-    }
 
     // Load the specified node:
     /** @var \Drupal\node\NodeInterface $node */
@@ -120,11 +116,9 @@ public function render($row) {
     // The node gets built and modules add to or modify $node->rss_elements
     // and $node->rss_namespaces.
 
-    $build_mode = $display_mode;
-
     $build = \Drupal::entityTypeManager()
       ->getViewBuilder('node')
-      ->view($node, $build_mode);
+      ->view($node, $display_mode);
     // Add rss key to cache to differentiate this from other caches.
     $build['#cache']['keys'][] = 'view_rss';
 
@@ -135,7 +129,7 @@ public function render($row) {
     }
 
     $item = new \stdClass();
-    if ($display_mode != 'title') {
+    if ($display_mode != $this::TITLE_VIEW_MODE) {
       // We render node contents.
       $item->description = $build;
     }
diff --git a/core/modules/system/config/install/system.rss.yml b/core/modules/system/config/install/system.rss.yml
deleted file mode 100644
index bb7c0c040a97..000000000000
--- a/core/modules/system/config/install/system.rss.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-items:
-  view_mode: rss
diff --git a/core/modules/system/config/schema/system.schema.yml b/core/modules/system/config/schema/system.schema.yml
index 88f34652b986..96cfabee126b 100644
--- a/core/modules/system/config/schema/system.schema.yml
+++ b/core/modules/system/config/schema/system.schema.yml
@@ -238,18 +238,6 @@ system.performance:
           type: boolean
           label: 'Compress JavaScript files.'
 
-system.rss:
-  type: config_object
-  label: 'Feed settings'
-  mapping:
-    items:
-      type: mapping
-      label: 'Feed items'
-      mapping:
-        view_mode:
-          type: string
-          label: 'Feed content'
-
 system.theme:
   type: config_object
   label: 'Theme settings'
diff --git a/core/modules/system/migrations/system_rss.yml b/core/modules/system/migrations/system_rss.yml
deleted file mode 100644
index 8a74ac6c84cf..000000000000
--- a/core/modules/system/migrations/system_rss.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-id: system_rss
-label: RSS configuration
-migration_tags:
-  - Drupal 6
-  - Drupal 7
-  - Configuration
-source:
-  plugin: variable
-  variables:
-    - feed_item_length
-  source_module: system
-process:
-  'items/view_mode': feed_item_length
-destination:
-  plugin: config
-  config_name: system.rss
diff --git a/core/modules/system/src/Form/RssFeedsForm.php b/core/modules/system/src/Form/RssFeedsForm.php
deleted file mode 100644
index 72617220f2c0..000000000000
--- a/core/modules/system/src/Form/RssFeedsForm.php
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-
-namespace Drupal\system\Form;
-
-use Drupal\Core\Form\ConfigFormBase;
-use Drupal\Core\Form\FormStateInterface;
-
-/**
- * Configure RSS settings for this site.
- *
- * @internal
- */
-class RssFeedsForm extends ConfigFormBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'system_rss_feeds_settings';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function getEditableConfigNames() {
-    return ['system.rss'];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state) {
-    $form['feed_view_mode'] = [
-      '#type' => 'select',
-      '#title' => $this->t('Feed content'),
-      '#config_target' => 'system.rss:items.view_mode',
-      '#options' => [
-        'title' => $this->t('Titles only'),
-        'teaser' => $this->t('Titles plus teaser'),
-        'fulltext' => $this->t('Full text'),
-      ],
-      '#description' => $this->t('Global setting for the default display of content items in each feed.'),
-    ];
-
-    return parent::buildForm($form, $form_state);
-  }
-
-}
diff --git a/core/modules/system/system.config_translation.yml b/core/modules/system/system.config_translation.yml
index 87cc98ce8716..e56f2395c36f 100644
--- a/core/modules/system/system.config_translation.yml
+++ b/core/modules/system/system.config_translation.yml
@@ -9,9 +9,3 @@ system.site_information_settings:
   base_route_name: system.site_information_settings
   names:
     - system.site
-
-system.rss_feeds_settings:
-  title: 'RSS publishing'
-  base_route_name: system.rss_feeds_settings
-  names:
-    - system.rss
diff --git a/core/modules/system/system.links.menu.yml b/core/modules/system/system.links.menu.yml
index 404bceeb7b36..ea9f1528530e 100644
--- a/core/modules/system/system.links.menu.yml
+++ b/core/modules/system/system.links.menu.yml
@@ -53,11 +53,6 @@ system.admin_config_services:
   title: 'Web services'
   parent: system.admin_config
   route_name: system.admin_config_services
-system.rss_feeds_settings:
-  title: 'RSS publishing'
-  parent: system.admin_config_services
-  description: 'Configure the site description, the number of items per feed, and whether feeds should be titles/teasers/full-text.'
-  route_name: system.rss_feeds_settings
 system.admin_config_development:
   route_name: system.admin_config_development
   parent: system.admin_config
diff --git a/core/modules/system/system.links.task.yml b/core/modules/system/system.links.task.yml
index ed66b0595e20..369cc253ad84 100644
--- a/core/modules/system/system.links.task.yml
+++ b/core/modules/system/system.links.task.yml
@@ -1,8 +1,3 @@
-system.rss_feeds_settings_tab:
-  route_name: system.rss_feeds_settings
-  title: Settings
-  base_route: system.rss_feeds_settings
-
 system.site_maintenance_mode_tab:
   route_name: system.site_maintenance_mode
   title: Settings
diff --git a/core/modules/system/system.post_update.php b/core/modules/system/system.post_update.php
index ce110e2c2f36..78876aaa74ef 100644
--- a/core/modules/system/system.post_update.php
+++ b/core/modules/system/system.post_update.php
@@ -123,3 +123,10 @@ function system_post_update_convert_empty_description_entity_form_modes_to_null(
     });
 
 }
+
+/**
+ * Delete obsolete system.rss configuration.
+ */
+function system_post_update_delete_rss_config(): void {
+  \Drupal::configFactory()->getEditable('system.rss')->delete();
+}
diff --git a/core/modules/system/system.routing.yml b/core/modules/system/system.routing.yml
index bf1ff4ca1f60..d3b67dd75177 100644
--- a/core/modules/system/system.routing.yml
+++ b/core/modules/system/system.routing.yml
@@ -191,14 +191,6 @@ system.file_system_settings:
   requirements:
     _permission: 'administer site configuration'
 
-system.rss_feeds_settings:
-  path: '/admin/config/services/rss-publishing'
-  defaults:
-    _form: '\Drupal\system\Form\RssFeedsForm'
-    _title: 'RSS publishing'
-  requirements:
-    _permission: 'administer site configuration'
-
 system.regional_settings:
   path: '/admin/config/regional/settings'
   defaults:
diff --git a/core/modules/system/tests/src/Functional/Update/SystemRssDeleteTest.php b/core/modules/system/tests/src/Functional/Update/SystemRssDeleteTest.php
new file mode 100644
index 000000000000..76d804c1af56
--- /dev/null
+++ b/core/modules/system/tests/src/Functional/Update/SystemRssDeleteTest.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace Drupal\Tests\system\Functional\Update;
+
+use Drupal\FunctionalTests\Update\UpdatePathTestBase;
+
+/**
+ * Tests that system.rss config is deleted.
+ *
+ * @group Update
+ * @see system_post_update_delete_rss_config()
+ */
+class SystemRssDeleteTest extends UpdatePathTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setDatabaseDumpFiles() {
+    $this->databaseDumpFiles = [
+      __DIR__ . '/../../../fixtures/update/drupal-10.3.0.bare.standard.php.gz',
+    ];
+  }
+
+  /**
+   * Ensures that system.rss is deleted after updating.
+   */
+  public function testUpdate() {
+    $config = $this->config('system.rss');
+    $this->assertFalse($config->isNew());
+
+    $this->runUpdates();
+
+    $config = $this->config('system.rss');
+    $this->assertTrue($config->isNew());
+  }
+
+}
diff --git a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemConfigurationTest.php b/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemConfigurationTest.php
index eba36bada4bb..28572e4e26fd 100644
--- a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemConfigurationTest.php
+++ b/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemConfigurationTest.php
@@ -95,11 +95,6 @@ class MigrateSystemConfigurationTest extends MigrateDrupal6TestBase {
         'gzip' => TRUE,
       ],
     ],
-    'system.rss' => [
-      'items' => [
-        'view_mode' => 'title',
-      ],
-    ],
     'system.site' => [
       // Neither langcode nor default_langcode are not handled by the migration.
       'langcode' => 'en',
@@ -141,7 +136,6 @@ protected function setUp(): void {
       'system_logging',
       'system_maintenance',
       'd6_system_performance',
-      'system_rss',
       'system_site',
     ];
     $this->executeMigrations($migrations);
diff --git a/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateSystemConfigurationTest.php b/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateSystemConfigurationTest.php
index b8b18a5c9ba2..b677e58d5482 100644
--- a/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateSystemConfigurationTest.php
+++ b/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateSystemConfigurationTest.php
@@ -107,11 +107,6 @@ class MigrateSystemConfigurationTest extends MigrateDrupal7TestBase {
         'gzip' => TRUE,
       ],
     ],
-    'system.rss' => [
-      'items' => [
-        'view_mode' => 'fulltext',
-      ],
-    ],
     'system.site' => [
       // Neither langcode nor default_langcode are not handled by the migration.
       'langcode' => 'en',
@@ -176,7 +171,6 @@ protected function setUp(): void {
       'd7_system_mail',
       'system_maintenance',
       'd7_system_performance',
-      'system_rss',
       'system_site',
     ];
     $this->executeMigrations($migrations);
diff --git a/core/modules/views/src/Plugin/views/row/RssPluginBase.php b/core/modules/views/src/Plugin/views/row/RssPluginBase.php
index 3de7d7af3a7b..418736427b85 100644
--- a/core/modules/views/src/Plugin/views/row/RssPluginBase.php
+++ b/core/modules/views/src/Plugin/views/row/RssPluginBase.php
@@ -12,6 +12,11 @@
  */
 abstract class RssPluginBase extends RowPluginBase {
 
+  /**
+   * A fake view mode to only display titles.
+   */
+  const string TITLE_VIEW_MODE = '_views.rss.title';
+
   /**
    * The entity type manager.
    *
@@ -73,7 +78,15 @@ public static function create(ContainerInterface $container, array $configuratio
   protected function defineOptions() {
     $options = parent::defineOptions();
 
-    $options['view_mode'] = ['default' => 'default'];
+    // Select the rss view mode by default, otherwise select the first available
+    // view mode.
+    $view_modes = $this->entityDisplayRepository->getViewModes($this->entityTypeId);
+    if (isset($view_modes['rss'])) {
+      $options['view_mode'] = ['default' => 'rss'];
+    }
+    else {
+      $options['view_mode'] = ['default' => key($view_modes)];
+    }
 
     return $options;
   }
-- 
GitLab


From b7e164f53e7c30dde01895cbd0b463caac1f72f1 Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Wed, 16 Apr 2025 09:46:18 +0200
Subject: [PATCH 02/23] build: fix missing return types

---
 .../tests/src/Functional/Update/SystemRssDeleteTest.php     | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/core/modules/system/tests/src/Functional/Update/SystemRssDeleteTest.php b/core/modules/system/tests/src/Functional/Update/SystemRssDeleteTest.php
index 76d804c1af56..e57357543742 100644
--- a/core/modules/system/tests/src/Functional/Update/SystemRssDeleteTest.php
+++ b/core/modules/system/tests/src/Functional/Update/SystemRssDeleteTest.php
@@ -1,5 +1,7 @@
 <?php
 
+declare(strict_types=1);
+
 namespace Drupal\Tests\system\Functional\Update;
 
 use Drupal\FunctionalTests\Update\UpdatePathTestBase;
@@ -15,7 +17,7 @@ class SystemRssDeleteTest extends UpdatePathTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setDatabaseDumpFiles() {
+  protected function setDatabaseDumpFiles(): void {
     $this->databaseDumpFiles = [
       __DIR__ . '/../../../fixtures/update/drupal-10.3.0.bare.standard.php.gz',
     ];
@@ -24,7 +26,7 @@ protected function setDatabaseDumpFiles() {
   /**
    * Ensures that system.rss is deleted after updating.
    */
-  public function testUpdate() {
+  public function testUpdate(): void {
     $config = $this->config('system.rss');
     $this->assertFalse($config->isNew());
 
-- 
GitLab


From 3a8210e3239ab44db9a39cdd48969d624818c4a2 Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Wed, 16 Apr 2025 23:59:56 +0200
Subject: [PATCH 03/23] feat: add test for upgrading views

---
 core/modules/system/system.post_update.php    |  19 +-
 core/modules/views/src/ViewsConfigUpdater.php |  23 +++
 .../fixtures/update/rss-default-view-mode.php |  21 ++
 .../update/views.view.test_display_feed.yml   | 193 ++++++++++++++++++
 .../RssDefaultRowViewModeUpdateTest.php       |  62 ++++++
 .../src/Kernel/ViewsConfigUpdaterTest.php     |  29 +++
 6 files changed, 345 insertions(+), 2 deletions(-)
 create mode 100644 core/modules/views/tests/fixtures/update/rss-default-view-mode.php
 create mode 100644 core/modules/views/tests/fixtures/update/views.view.test_display_feed.yml
 create mode 100644 core/modules/views/tests/src/Functional/Update/RssDefaultRowViewModeUpdateTest.php

diff --git a/core/modules/system/system.post_update.php b/core/modules/system/system.post_update.php
index 78876aaa74ef..cd940e2b711d 100644
--- a/core/modules/system/system.post_update.php
+++ b/core/modules/system/system.post_update.php
@@ -7,6 +7,8 @@
 
 use Drupal\Core\Config\Entity\ConfigEntityUpdater;
 use Drupal\Core\Entity\EntityFormModeInterface;
+use Drupal\views\ViewEntityInterface;
+use Drupal\views\ViewsConfigUpdater;
 
 /**
  * Implements hook_removed_post_updates().
@@ -127,6 +129,19 @@ function system_post_update_convert_empty_description_entity_form_modes_to_null(
 /**
  * Delete obsolete system.rss configuration.
  */
-function system_post_update_delete_rss_config(): void {
-  \Drupal::configFactory()->getEditable('system.rss')->delete();
+function system_post_update_delete_rss_config(array &$sandbox): void {
+  $config = \Drupal::configFactory()->getEditable('system.rss');
+  $previous_view_mode = $config->get('items.view_mode');
+  if ($config->get('items.view_mode') !== NULL) {
+    $sandbox['#system_post_update_delete_rss_config_previous_view_mode'] = $previous_view_mode;
+  }
+
+  /** @var \Drupal\views\ViewsConfigUpdater $view_config_updater */
+  $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class);
+  $view_config_updater->setDeprecationsEnabled(FALSE);
+  \Drupal::classResolver(ConfigEntityUpdater::class)->update($sandbox, 'view', function (ViewEntityInterface $view) use ($view_config_updater, $sandbox): bool {
+    return $view_config_updater->needsRssViewModeUpdate($view, $sandbox['#system_post_update_delete_rss_config_previous_view_mode']);
+  });
+
+  $config->delete();
 }
diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php
index 9c5d38e10ac5..b11e6caa5a6e 100644
--- a/core/modules/views/src/ViewsConfigUpdater.php
+++ b/core/modules/views/src/ViewsConfigUpdater.php
@@ -359,4 +359,27 @@ public function processTableCssClassUpdate(ViewEntityInterface $view): bool {
     return $changed;
   }
 
+  public function needsRssViewModeUpdate(ViewEntityInterface $view, ?string $previous_view_mode): bool {
+    return $this->processRssViewModeUpdate($view, $previous_view_mode);
+  }
+
+  public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $previous_view_mode) : bool {
+    $changed = FALSE;
+    $displays = $view->get('display');
+
+    foreach ($displays as &$display) {
+      if (isset($display['display_options']['row']['options']['view_mode']) &&
+        $display['display_options']['row']['options']['view_mode'] === 'default') {
+        $display['display_options']['row']['options']['view_mode'] = $previous_view_mode;
+        $changed = TRUE;
+      }
+    }
+
+    if ($changed) {
+      $view->set('display', $displays);
+    }
+
+    return $changed;
+  }
+
 }
diff --git a/core/modules/views/tests/fixtures/update/rss-default-view-mode.php b/core/modules/views/tests/fixtures/update/rss-default-view-mode.php
new file mode 100644
index 000000000000..6d7c83ff8941
--- /dev/null
+++ b/core/modules/views/tests/fixtures/update/rss-default-view-mode.php
@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * @file
+ * Test fixture.
+ */
+
+use Drupal\Core\Database\Database;
+use Drupal\Component\Serialization\Yaml;
+
+$connection = Database::getConnection();
+
+$config = Yaml::decode(file_get_contents(__DIR__ . '/views.view.test_display_feed.yml'));
+
+$connection->insert('config')
+  ->fields([
+    'collection' => '',
+    'name' => 'views.view.test_display_feed',
+    'data' => serialize($config),
+  ])
+  ->execute();
diff --git a/core/modules/views/tests/fixtures/update/views.view.test_display_feed.yml b/core/modules/views/tests/fixtures/update/views.view.test_display_feed.yml
new file mode 100644
index 000000000000..0dd06c7ecf76
--- /dev/null
+++ b/core/modules/views/tests/fixtures/update/views.view.test_display_feed.yml
@@ -0,0 +1,193 @@
+uuid: 06456283-a609-4646-aeb4-f2b918b13111
+langcode: en
+status: true
+dependencies:
+  config:
+    - core.entity_view_mode.node.rss
+  module:
+    - node
+    - user
+id: test_display_feed
+label: 'rss test view'
+module: views
+description: ''
+tag: ''
+base_table: node_field_data
+base_field: nid
+display:
+  default:
+    id: default
+    display_title: Default
+    display_plugin: default
+    position: 0
+    display_options:
+      fields:
+        title:
+          id: title
+          table: node_field_data
+          field: title
+          relationship: none
+          group_type: group
+          admin_label: ''
+          entity_type: node
+          entity_field: title
+          plugin_id: field
+          label: ''
+          exclude: false
+          alter:
+            alter_text: false
+            make_link: false
+            absolute: false
+            word_boundary: false
+            ellipsis: false
+            strip_tags: false
+            trim: false
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: string
+          settings:
+            link_to_entity: true
+          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
+      pager:
+        type: mini
+        options:
+          offset: 0
+          pagination_heading_level: h4
+          items_per_page: 10
+          total_pages: null
+          id: 0
+          tags:
+            next: ››
+            previous: ‹‹
+          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
+      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
+      access:
+        type: perm
+        options:
+          perm: 'access content'
+      cache:
+        type: tag
+        options: {  }
+      empty: {  }
+      sorts:
+        created:
+          id: created
+          table: node_field_data
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          entity_type: node
+          entity_field: created
+          plugin_id: date
+          order: DESC
+          expose:
+            label: ''
+            field_identifier: ''
+          exposed: false
+          granularity: second
+      arguments: {  }
+      filters:
+        status:
+          id: status
+          table: node_field_data
+          field: status
+          entity_type: node
+          entity_field: status
+          plugin_id: boolean
+          value: '1'
+          group: 1
+          expose:
+            operator: ''
+      style:
+        type: default
+        options:
+          grouping: {  }
+          row_class: ''
+          default_row_class: true
+          uses_fields: false
+      row:
+        type: fields
+        options:
+          default_field_elements: true
+          inline: {  }
+          separator: ''
+          hide_empty: false
+      query:
+        type: views_query
+        options:
+          query_comment: ''
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_tags: {  }
+      relationships: {  }
+      header: {  }
+      footer: {  }
+      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:
+    id: feed_1
+    display_title: Feed
+    display_plugin: feed
+    position: 1
+    display_options:
+      row:
+        type: node_rss
+        options:
+          view_mode: default
+      display_extenders: {  }
+      path: my-feed.xml
+    cache_metadata:
+      max-age: -1
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - 'user.node_grants:view'
+        - user.permissions
+      tags: {  }
diff --git a/core/modules/views/tests/src/Functional/Update/RssDefaultRowViewModeUpdateTest.php b/core/modules/views/tests/src/Functional/Update/RssDefaultRowViewModeUpdateTest.php
new file mode 100644
index 000000000000..9de7132cdf7c
--- /dev/null
+++ b/core/modules/views/tests/src/Functional/Update/RssDefaultRowViewModeUpdateTest.php
@@ -0,0 +1,62 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Tests\views\Functional\Update;
+
+use Drupal\FunctionalTests\Update\UpdatePathTestBase;
+use Drupal\views\Entity\View;
+
+/**
+ * Tests the update view mode when removing system.rss.
+ *
+ * @see system_post_update_delete_rss_config()
+ *
+ * @group Update
+ * @group legacy
+ */
+class RssDefaultRowViewModeUpdateTest extends UpdatePathTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = ['node', 'user'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setDatabaseDumpFiles(): void {
+    $this->databaseDumpFiles = [
+      __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-10.3.0.filled.standard.php.gz',
+      __DIR__ . '/../../../fixtures/update/rss-default-view-mode.php',
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp(): void {
+    parent::setUp();
+
+    $this->installModulesFromClassProperty($this->container);
+  }
+
+  /**
+   * Tests the upgrade path setting rss row view mode.
+   */
+  public function testRssDefaultRowViewModeUpdate(): void {
+    $views = View::loadMultiple();
+    $data = $views['test_display_feed']->toArray();
+
+    $this->assertEquals('default', $data['display']['feed_1']['display_options']['row']['options']['view_mode']);
+
+    $this->runUpdates();
+
+    $views = View::loadMultiple();
+    $data = $views['test_display_feed']->toArray();
+
+    $this->assertEquals('title', $data['display']['feed_1']['display_options']['row']['options']['view_mode']);
+
+  }
+
+}
diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
index b99adcd105d8..9d6b83da89e3 100644
--- a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
+++ b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
@@ -5,6 +5,7 @@
 namespace Drupal\Tests\views\Kernel;
 
 use Drupal\Core\Config\FileStorage;
+use Drupal\views\ViewsConfigUpdater;
 
 /**
  * @coversDefaultClass \Drupal\views\ViewsConfigUpdater
@@ -32,6 +33,34 @@ public function testViewsConfigUpdater(): void {
     $this->markTestSkipped();
   }
 
+  /**
+   * Tests the `updateRssViewMode` method to ensure it correctly updates the
+   * view mode for RSS feed displays.
+   */
+  public function testUpdateRssViewMode(): void {
+    $this->strictConfigSchema = FALSE;
+
+    /** @var \Drupal\views\ViewsConfigUpdater $view_config_updater */
+    $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class);
+
+    // Load the test view.
+    $view_id = 'views.view.test_display_feed_view_mode';
+    $test_view = $this->loadTestView($view_id);
+    $display = $test_view->getDisplay('feed_1');
+
+    // Check the initial view mode.
+    $rowViewMode = $display['display_options']['row']['options']['view_mode'] ?? FALSE;
+    $this->assertEquals('default', $rowViewMode);
+
+    // Update the view mode using the method under test.
+    $view_config_updater->needsRssViewModeUpdate($test_view, 'old_view_mode');
+
+    // Assert if the view mode was updated correctly.
+    $display = $test_view->getDisplay('feed_1');
+    $updatedRowViewMode = $display['display_options']['row']['options']['view_mode'] ?? FALSE;
+    $this->assertEquals('old_view_mode', $updatedRowViewMode);
+  }
+
   /**
    * Loads a test view.
    *
-- 
GitLab


From 1905479ffba1de6fcca1422ee885fc7f986ca14b Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Thu, 17 Apr 2025 00:10:06 +0200
Subject: [PATCH 04/23] fix: small fix

---
 core/modules/system/system.post_update.php                    | 4 ++--
 .../modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php | 3 +--
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/core/modules/system/system.post_update.php b/core/modules/system/system.post_update.php
index cd940e2b711d..3d762ba862d8 100644
--- a/core/modules/system/system.post_update.php
+++ b/core/modules/system/system.post_update.php
@@ -133,14 +133,14 @@ function system_post_update_delete_rss_config(array &$sandbox): void {
   $config = \Drupal::configFactory()->getEditable('system.rss');
   $previous_view_mode = $config->get('items.view_mode');
   if ($config->get('items.view_mode') !== NULL) {
-    $sandbox['#system_post_update_delete_rss_config_previous_view_mode'] = $previous_view_mode;
+    $sandbox['#system_post_update_delete_rss_config__previous_view_mode'] = $previous_view_mode;
   }
 
   /** @var \Drupal\views\ViewsConfigUpdater $view_config_updater */
   $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class);
   $view_config_updater->setDeprecationsEnabled(FALSE);
   \Drupal::classResolver(ConfigEntityUpdater::class)->update($sandbox, 'view', function (ViewEntityInterface $view) use ($view_config_updater, $sandbox): bool {
-    return $view_config_updater->needsRssViewModeUpdate($view, $sandbox['#system_post_update_delete_rss_config_previous_view_mode']);
+    return $view_config_updater->needsRssViewModeUpdate($view, $sandbox['#system_post_update_delete_rss_config__previous_view_mode']);
   });
 
   $config->delete();
diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
index 9d6b83da89e3..fd9095865c11 100644
--- a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
+++ b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
@@ -34,8 +34,7 @@ public function testViewsConfigUpdater(): void {
   }
 
   /**
-   * Tests the `updateRssViewMode` method to ensure it correctly updates the
-   * view mode for RSS feed displays.
+   * Tests the `needsRssViewModeUpdate` method.
    */
   public function testUpdateRssViewMode(): void {
     $this->strictConfigSchema = FALSE;
-- 
GitLab


From a1ef022c44306020ab573b634ec08c8699ad64e4 Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Thu, 17 Apr 2025 00:13:14 +0200
Subject: [PATCH 05/23] fix: don't need modules

---
 .../Update/RssDefaultRowViewModeUpdateTest.php     | 14 --------------
 1 file changed, 14 deletions(-)

diff --git a/core/modules/views/tests/src/Functional/Update/RssDefaultRowViewModeUpdateTest.php b/core/modules/views/tests/src/Functional/Update/RssDefaultRowViewModeUpdateTest.php
index 9de7132cdf7c..e524362dd9ff 100644
--- a/core/modules/views/tests/src/Functional/Update/RssDefaultRowViewModeUpdateTest.php
+++ b/core/modules/views/tests/src/Functional/Update/RssDefaultRowViewModeUpdateTest.php
@@ -17,11 +17,6 @@
  */
 class RssDefaultRowViewModeUpdateTest extends UpdatePathTestBase {
 
-  /**
-   * {@inheritdoc}
-   */
-  protected static $modules = ['node', 'user'];
-
   /**
    * {@inheritdoc}
    */
@@ -32,15 +27,6 @@ protected function setDatabaseDumpFiles(): void {
     ];
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp(): void {
-    parent::setUp();
-
-    $this->installModulesFromClassProperty($this->container);
-  }
-
   /**
    * Tests the upgrade path setting rss row view mode.
    */
-- 
GitLab


From cfc345d9cf9f3d4373ff14f40d8c6090e4b8f8cb Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Thu, 17 Apr 2025 11:54:25 +0200
Subject: [PATCH 06/23] fix: make the test work again after since the fixture
 was renamed

---
 core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
index fd9095865c11..68384106b454 100644
--- a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
+++ b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
@@ -43,7 +43,7 @@ public function testUpdateRssViewMode(): void {
     $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class);
 
     // Load the test view.
-    $view_id = 'views.view.test_display_feed_view_mode';
+    $view_id = 'views.view.test_display_feed';
     $test_view = $this->loadTestView($view_id);
     $display = $test_view->getDisplay('feed_1');
 
-- 
GitLab


From c38664966b18003e291c321e9a588bfef0f29aff Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Thu, 17 Apr 2025 16:14:13 +0200
Subject: [PATCH 07/23] feat: wrap system update view update with a moduleExist
 call.

---
 core/modules/system/system.post_update.php | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/core/modules/system/system.post_update.php b/core/modules/system/system.post_update.php
index 3d762ba862d8..c83de1019444 100644
--- a/core/modules/system/system.post_update.php
+++ b/core/modules/system/system.post_update.php
@@ -136,12 +136,15 @@ function system_post_update_delete_rss_config(array &$sandbox): void {
     $sandbox['#system_post_update_delete_rss_config__previous_view_mode'] = $previous_view_mode;
   }
 
-  /** @var \Drupal\views\ViewsConfigUpdater $view_config_updater */
-  $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class);
-  $view_config_updater->setDeprecationsEnabled(FALSE);
-  \Drupal::classResolver(ConfigEntityUpdater::class)->update($sandbox, 'view', function (ViewEntityInterface $view) use ($view_config_updater, $sandbox): bool {
-    return $view_config_updater->needsRssViewModeUpdate($view, $sandbox['#system_post_update_delete_rss_config__previous_view_mode']);
-  });
+  if (\Drupal::moduleHandler()->moduleExists('views')) {
+    /** @var \Drupal\views\ViewsConfigUpdater $view_config_updater */
+    $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class);
+    $view_config_updater->setDeprecationsEnabled(FALSE);
+    \Drupal::classResolver(ConfigEntityUpdater::class)
+      ->update($sandbox, 'view', function(ViewEntityInterface $view) use ($view_config_updater, $sandbox): bool {
+        return $view_config_updater->needsRssViewModeUpdate($view, $sandbox['#system_post_update_delete_rss_config__previous_view_mode']);
+      });
+  }
 
   $config->delete();
 }
-- 
GitLab


From 8eec5acc24c5be24a17f7852dba2e977f27e2375 Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Fri, 18 Apr 2025 12:16:14 +0200
Subject: [PATCH 08/23] fix: ViewsConfigUpdater should only update views of
 which the row: type: are node_rss or comment_rss

---
 core/modules/views/src/ViewsConfigUpdater.php |   7 +
 .../views.view.test_display_feed_noupdate.yml | 193 ++++++++++++++++++
 .../src/Kernel/ViewsConfigUpdaterTest.php     |  27 +++
 3 files changed, 227 insertions(+)
 create mode 100644 core/modules/views/tests/fixtures/update/views.view.test_display_feed_noupdate.yml

diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php
index b11e6caa5a6e..7ce518a74ac8 100644
--- a/core/modules/views/src/ViewsConfigUpdater.php
+++ b/core/modules/views/src/ViewsConfigUpdater.php
@@ -367,8 +367,15 @@ public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $pre
     $changed = FALSE;
     $displays = $view->get('display');
 
+    // Row types that need updating.
+    $row_types = [
+      'comment_rss',
+      'node_rss',
+    ];
+
     foreach ($displays as &$display) {
       if (isset($display['display_options']['row']['options']['view_mode']) &&
+        in_array($display['display_options']['row']['type'], $row_types, TRUE) &&
         $display['display_options']['row']['options']['view_mode'] === 'default') {
         $display['display_options']['row']['options']['view_mode'] = $previous_view_mode;
         $changed = TRUE;
diff --git a/core/modules/views/tests/fixtures/update/views.view.test_display_feed_noupdate.yml b/core/modules/views/tests/fixtures/update/views.view.test_display_feed_noupdate.yml
new file mode 100644
index 000000000000..b173d4ca57ca
--- /dev/null
+++ b/core/modules/views/tests/fixtures/update/views.view.test_display_feed_noupdate.yml
@@ -0,0 +1,193 @@
+uuid: 06456283-a609-4646-aeb4-f2b918b13111
+langcode: en
+status: true
+dependencies:
+  config:
+    - core.entity_view_mode.node.rss
+  module:
+    - node
+    - user
+id: test_display_feed_noupdate
+label: 'rss test view'
+module: views
+description: ''
+tag: ''
+base_table: node_field_data
+base_field: nid
+display:
+  default:
+    id: default
+    display_title: Default
+    display_plugin: default
+    position: 0
+    display_options:
+      fields:
+        title:
+          id: title
+          table: node_field_data
+          field: title
+          relationship: none
+          group_type: group
+          admin_label: ''
+          entity_type: node
+          entity_field: title
+          plugin_id: field
+          label: ''
+          exclude: false
+          alter:
+            alter_text: false
+            make_link: false
+            absolute: false
+            word_boundary: false
+            ellipsis: false
+            strip_tags: false
+            trim: false
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: string
+          settings:
+            link_to_entity: true
+          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
+      pager:
+        type: mini
+        options:
+          offset: 0
+          pagination_heading_level: h4
+          items_per_page: 10
+          total_pages: null
+          id: 0
+          tags:
+            next: ››
+            previous: ‹‹
+          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
+      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
+      access:
+        type: perm
+        options:
+          perm: 'access content'
+      cache:
+        type: tag
+        options: {  }
+      empty: {  }
+      sorts:
+        created:
+          id: created
+          table: node_field_data
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          entity_type: node
+          entity_field: created
+          plugin_id: date
+          order: DESC
+          expose:
+            label: ''
+            field_identifier: ''
+          exposed: false
+          granularity: second
+      arguments: {  }
+      filters:
+        status:
+          id: status
+          table: node_field_data
+          field: status
+          entity_type: node
+          entity_field: status
+          plugin_id: boolean
+          value: '1'
+          group: 1
+          expose:
+            operator: ''
+      style:
+        type: default
+        options:
+          grouping: {  }
+          row_class: ''
+          default_row_class: true
+          uses_fields: false
+      row:
+        type: fields
+        options:
+          default_field_elements: true
+          inline: {  }
+          separator: ''
+          hide_empty: false
+      query:
+        type: views_query
+        options:
+          query_comment: ''
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_tags: {  }
+      relationships: {  }
+      header: {  }
+      footer: {  }
+      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:
+    id: feed_1
+    display_title: Feed
+    display_plugin: feed
+    position: 1
+    display_options:
+      row:
+        type: entity:node
+        options:
+          view_mode: default
+      display_extenders: {  }
+      path: my-feed.xml
+    cache_metadata:
+      max-age: -1
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - 'user.node_grants:view'
+        - user.permissions
+      tags: {  }
diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
index 68384106b454..3173680a5a02 100644
--- a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
+++ b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
@@ -60,6 +60,33 @@ public function testUpdateRssViewMode(): void {
     $this->assertEquals('old_view_mode', $updatedRowViewMode);
   }
 
+  /**
+   * Tests the `needsRssViewModeUpdate` method.
+   */
+  public function testUpdateRssViewModeSkipsOtherType(): void {
+    $this->strictConfigSchema = FALSE;
+
+    /** @var \Drupal\views\ViewsConfigUpdater $view_config_updater */
+    $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class);
+
+    // Load the test view.
+    $view_id = 'views.view.test_display_feed_noupdate';
+    $test_view = $this->loadTestView($view_id);
+    $display = $test_view->getDisplay('feed_1');
+
+    // Check the initial view mode.
+    $rowViewMode = $display['display_options']['row']['options']['view_mode'] ?? FALSE;
+    $this->assertEquals('default', $rowViewMode);
+
+    // Update the view mode using the method under test.
+    $view_config_updater->needsRssViewModeUpdate($test_view, 'old_view_mode');
+
+    // Assert if the view mode was updated correctly.
+    $display = $test_view->getDisplay('feed_1');
+    $updatedRowViewMode = $display['display_options']['row']['options']['view_mode'] ?? FALSE;
+    $this->assertEquals('default', $updatedRowViewMode);
+  }
+
   /**
    * Loads a test view.
    *
-- 
GitLab


From e8b6853bf6b5d843d8fae74e96e2b691b1869b3f Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Fri, 18 Apr 2025 12:40:54 +0200
Subject: [PATCH 09/23] fix: Get the first available viewmode for the comment
 or node if the system.rss setting is missing.

---
 core/modules/views/src/ViewsConfigUpdater.php | 22 ++++++++----
 .../src/Kernel/ViewsConfigUpdaterTest.php     | 34 +++++++++++++++++++
 2 files changed, 49 insertions(+), 7 deletions(-)

diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php
index 7ce518a74ac8..7f64368027ac 100644
--- a/core/modules/views/src/ViewsConfigUpdater.php
+++ b/core/modules/views/src/ViewsConfigUpdater.php
@@ -5,6 +5,7 @@
 use Drupal\Component\Plugin\PluginManagerInterface;
 use Drupal\Core\Config\TypedConfigManagerInterface;
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
+use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
 use Drupal\Core\Entity\EntityFieldManagerInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -85,6 +86,7 @@ public function __construct(
     TypedConfigManagerInterface $typed_config_manager,
     ViewsData $views_data,
     PluginManagerInterface $formatter_plugin_manager,
+    protected EntityDisplayRepositoryInterface $entityDisplayRepository,
   ) {
     $this->entityTypeManager = $entity_type_manager;
     $this->entityFieldManager = $entity_field_manager;
@@ -102,7 +104,8 @@ public static function create(ContainerInterface $container) {
       $container->get('entity_field.manager'),
       $container->get('config.typed'),
       $container->get('views.views_data'),
-      $container->get('plugin.manager.field.formatter')
+      $container->get('plugin.manager.field.formatter'),
+      $container->get('entity_display.repository')
     );
   }
 
@@ -359,25 +362,30 @@ public function processTableCssClassUpdate(ViewEntityInterface $view): bool {
     return $changed;
   }
 
-  public function needsRssViewModeUpdate(ViewEntityInterface $view, ?string $previous_view_mode): bool {
+  public function needsRssViewModeUpdate(ViewEntityInterface $view, ?string $previous_view_mode = NULL): bool {
     return $this->processRssViewModeUpdate($view, $previous_view_mode);
   }
 
-  public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $previous_view_mode) : bool {
+  public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $previous_view_mode = NULL) : bool {
     $changed = FALSE;
     $displays = $view->get('display');
 
     // Row types that need updating.
     $row_types = [
-      'comment_rss',
-      'node_rss',
+      'comment_rss' => 'comment',
+      'node_rss' => 'node',
     ];
 
     foreach ($displays as &$display) {
       if (isset($display['display_options']['row']['options']['view_mode']) &&
-        in_array($display['display_options']['row']['type'], $row_types, TRUE) &&
+        array_key_exists($display['display_options']['row']['type'], $row_types) &&
         $display['display_options']['row']['options']['view_mode'] === 'default') {
-        $display['display_options']['row']['options']['view_mode'] = $previous_view_mode;
+        if ($previous_view_mode === NULL) {
+          $view_modes = $this->entityDisplayRepository->getViewModes($row_types[$display['display_options']['row']['type']]);
+          $display['display_options']['row']['options']['view_mode'] = array_key_first($view_modes);
+        } else {
+          $display['display_options']['row']['options']['view_mode'] = $previous_view_mode;
+        }
         $changed = TRUE;
       }
     }
diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
index 3173680a5a02..39d3f9744112 100644
--- a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
+++ b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
@@ -21,7 +21,9 @@ class ViewsConfigUpdaterTest extends ViewsKernelTestBase {
   protected static $modules = [
     'views_config_entity_test',
     'entity_test',
+    'text',
     'field',
+    'node',
   ];
 
   /**
@@ -60,6 +62,38 @@ public function testUpdateRssViewMode(): void {
     $this->assertEquals('old_view_mode', $updatedRowViewMode);
   }
 
+  /**
+   * Tests the `needsRssViewModeUpdate` method.
+   */
+  public function testUpdateRssViewModeWithoutKnownPreviousMode(): void {
+    $this->installEntitySchema('node');
+    $this->installConfig(['text', 'field', 'node']);
+
+    $this->strictConfigSchema = FALSE;
+
+    /** @var \Drupal\views\ViewsConfigUpdater $view_config_updater */
+    $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class);
+
+    // Load the test view.
+    $view_id = 'views.view.test_display_feed';
+    $test_view = $this->loadTestView($view_id);
+    $display = $test_view->getDisplay('feed_1');
+
+    // Check the initial view mode.
+    $rowViewMode = $display['display_options']['row']['options']['view_mode'] ?? FALSE;
+    $this->assertEquals('default', $rowViewMode);
+
+    // Update the view mode using the method under test.
+    $view_config_updater->needsRssViewModeUpdate($test_view);
+
+    // Assert if the view mode was updated correctly.
+    $display = $test_view->getDisplay('feed_1');
+    $updatedRowViewMode = $display['display_options']['row']['options']['view_mode'] ?? FALSE;
+
+    // This should be the first node view mode since we have nothing else
+    $this->assertEquals('teaser', $updatedRowViewMode);
+  }
+
   /**
    * Tests the `needsRssViewModeUpdate` method.
    */
-- 
GitLab


From b4de63390d24720f782e98c3336edc6599d1d75b Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Fri, 18 Apr 2025 12:44:25 +0200
Subject: [PATCH 10/23] build: fix phpcs and spelling error

---
 core/modules/system/system.post_update.php                      | 2 +-
 core/modules/views/src/ViewsConfigUpdater.php                   | 2 ++
 ..._noupdate.yml => views.view.test_display_feed_no_update.yml} | 2 +-
 core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php  | 2 +-
 4 files changed, 5 insertions(+), 3 deletions(-)
 rename core/modules/views/tests/fixtures/update/{views.view.test_display_feed_noupdate.yml => views.view.test_display_feed_no_update.yml} (99%)

diff --git a/core/modules/system/system.post_update.php b/core/modules/system/system.post_update.php
index c83de1019444..2ad4b290ba92 100644
--- a/core/modules/system/system.post_update.php
+++ b/core/modules/system/system.post_update.php
@@ -141,7 +141,7 @@ function system_post_update_delete_rss_config(array &$sandbox): void {
     $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class);
     $view_config_updater->setDeprecationsEnabled(FALSE);
     \Drupal::classResolver(ConfigEntityUpdater::class)
-      ->update($sandbox, 'view', function(ViewEntityInterface $view) use ($view_config_updater, $sandbox): bool {
+      ->update($sandbox, 'view', function (ViewEntityInterface $view) use ($view_config_updater, $sandbox): bool {
         return $view_config_updater->needsRssViewModeUpdate($view, $sandbox['#system_post_update_delete_rss_config__previous_view_mode']);
       });
   }
diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php
index 7f64368027ac..2355c1ce6d0e 100644
--- a/core/modules/views/src/ViewsConfigUpdater.php
+++ b/core/modules/views/src/ViewsConfigUpdater.php
@@ -79,6 +79,8 @@ class ViewsConfigUpdater implements ContainerInjectionInterface {
    *   The views data service.
    * @param \Drupal\Component\Plugin\PluginManagerInterface $formatter_plugin_manager
    *   The formatter plugin manager service.
+   * @param \Drupal\Core\Entity\EntityDisplayRepositoryInterface $entityDisplayRepository
+   *   The entity display repository service.
    */
   public function __construct(
     EntityTypeManagerInterface $entity_type_manager,
diff --git a/core/modules/views/tests/fixtures/update/views.view.test_display_feed_noupdate.yml b/core/modules/views/tests/fixtures/update/views.view.test_display_feed_no_update.yml
similarity index 99%
rename from core/modules/views/tests/fixtures/update/views.view.test_display_feed_noupdate.yml
rename to core/modules/views/tests/fixtures/update/views.view.test_display_feed_no_update.yml
index b173d4ca57ca..187ae2a2ddb0 100644
--- a/core/modules/views/tests/fixtures/update/views.view.test_display_feed_noupdate.yml
+++ b/core/modules/views/tests/fixtures/update/views.view.test_display_feed_no_update.yml
@@ -7,7 +7,7 @@ dependencies:
   module:
     - node
     - user
-id: test_display_feed_noupdate
+id: test_display_feed_no_update
 label: 'rss test view'
 module: views
 description: ''
diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
index 39d3f9744112..9f215ac3367e 100644
--- a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
+++ b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
@@ -104,7 +104,7 @@ public function testUpdateRssViewModeSkipsOtherType(): void {
     $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class);
 
     // Load the test view.
-    $view_id = 'views.view.test_display_feed_noupdate';
+    $view_id = 'views.view.test_display_feed_no_update';
     $test_view = $this->loadTestView($view_id);
     $display = $test_view->getDisplay('feed_1');
 
-- 
GitLab


From 3e13ca1fd50265f7530e0d40495b686d1529a224 Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Fri, 18 Apr 2025 12:56:03 +0200
Subject: [PATCH 11/23] build: fix phpcs error

---
 core/modules/views/src/ViewsConfigUpdater.php | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php
index 2355c1ce6d0e..c197c6ef73ba 100644
--- a/core/modules/views/src/ViewsConfigUpdater.php
+++ b/core/modules/views/src/ViewsConfigUpdater.php
@@ -385,7 +385,8 @@ public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $pre
         if ($previous_view_mode === NULL) {
           $view_modes = $this->entityDisplayRepository->getViewModes($row_types[$display['display_options']['row']['type']]);
           $display['display_options']['row']['options']['view_mode'] = array_key_first($view_modes);
-        } else {
+        }
+        else {
           $display['display_options']['row']['options']['view_mode'] = $previous_view_mode;
         }
         $changed = TRUE;
-- 
GitLab


From 6e60a9f9b649cea59337889d83682bae97b75d92 Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Fri, 18 Apr 2025 13:17:04 +0200
Subject: [PATCH 12/23] feat: also update views on save

---
 core/modules/views/src/ViewsConfigUpdater.php | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php
index c197c6ef73ba..e6cd65b3fcc6 100644
--- a/core/modules/views/src/ViewsConfigUpdater.php
+++ b/core/modules/views/src/ViewsConfigUpdater.php
@@ -142,6 +142,9 @@ public function updateAll(ViewEntityInterface $view) {
       if ($this->processTableCssClassUpdate($view)) {
         $changed = TRUE;
       }
+      if ($this->processRssViewModeUpdate($view)) {
+        $changed = TRUE;
+      }
       return $changed;
     });
   }
@@ -384,12 +387,16 @@ public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $pre
         $display['display_options']['row']['options']['view_mode'] === 'default') {
         if ($previous_view_mode === NULL) {
           $view_modes = $this->entityDisplayRepository->getViewModes($row_types[$display['display_options']['row']['type']]);
-          $display['display_options']['row']['options']['view_mode'] = array_key_first($view_modes);
+          $probable_view_mode = array_key_first($view_modes);
+          $display['display_options']['row']['options']['view_mode'] = $probable_view_mode;
+          if ($probable_view_mode !== 'default') {
+            $changed = TRUE;
+          }
         }
         else {
           $display['display_options']['row']['options']['view_mode'] = $previous_view_mode;
+          $changed = TRUE;
         }
-        $changed = TRUE;
       }
     }
 
-- 
GitLab


From 105fe07d0b5840d65a2353b4bfec195085f81774 Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Fri, 18 Apr 2025 13:19:31 +0200
Subject: [PATCH 13/23] feat: if there is a "default" view mode, just use that,
 since we don't want to loop around indefinitely

---
 core/modules/views/src/ViewsConfigUpdater.php | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php
index e6cd65b3fcc6..b0f25007a237 100644
--- a/core/modules/views/src/ViewsConfigUpdater.php
+++ b/core/modules/views/src/ViewsConfigUpdater.php
@@ -387,11 +387,12 @@ public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $pre
         $display['display_options']['row']['options']['view_mode'] === 'default') {
         if ($previous_view_mode === NULL) {
           $view_modes = $this->entityDisplayRepository->getViewModes($row_types[$display['display_options']['row']['type']]);
+          if (array_key_exists('default', $view_modes)) {
+            return FALSE;
+          }
+
           $probable_view_mode = array_key_first($view_modes);
           $display['display_options']['row']['options']['view_mode'] = $probable_view_mode;
-          if ($probable_view_mode !== 'default') {
-            $changed = TRUE;
-          }
         }
         else {
           $display['display_options']['row']['options']['view_mode'] = $previous_view_mode;
-- 
GitLab


From 9efddd6362bf30bdc4ec4151bb21ccd2b46cc887 Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Sat, 19 Apr 2025 07:53:52 +0200
Subject: [PATCH 14/23] fix: views.view.taxonomy_term default view_mode changed
 to rss

---
 .../taxonomy/config/optional/views.view.taxonomy_term.yml       | 2 +-
 .../demo_umami/config/install/views.view.taxonomy_term.yml      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml b/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml
index 9763c3c057dc..01834a39ac2f 100644
--- a/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml
+++ b/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml
@@ -277,7 +277,7 @@ display:
         type: node_rss
         options:
           relationship: none
-          view_mode: default
+          view_mode: rss
       query:
         type: views_query
         options: {  }
diff --git a/core/profiles/demo_umami/config/install/views.view.taxonomy_term.yml b/core/profiles/demo_umami/config/install/views.view.taxonomy_term.yml
index 4834b785f4f6..fbd65897f3a3 100644
--- a/core/profiles/demo_umami/config/install/views.view.taxonomy_term.yml
+++ b/core/profiles/demo_umami/config/install/views.view.taxonomy_term.yml
@@ -283,7 +283,7 @@ display:
         type: node_rss
         options:
           relationship: none
-          view_mode: default
+          view_mode: rss
       query:
         type: views_query
         options: {  }
-- 
GitLab


From f2b4e17204fb3017b01b1d25fd78dca8abfb83ea Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Sat, 19 Apr 2025 08:06:54 +0200
Subject: [PATCH 15/23] fix: add missing config dependencies for
 views.view.taxonomy_term.yml

---
 .../taxonomy/config/optional/views.view.taxonomy_term.yml        | 1 +
 .../demo_umami/config/install/views.view.taxonomy_term.yml       | 1 +
 2 files changed, 2 insertions(+)

diff --git a/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml b/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml
index 01834a39ac2f..eb6ad6ab3624 100644
--- a/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml
+++ b/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml
@@ -3,6 +3,7 @@ status: true
 dependencies:
   config:
     - core.entity_view_mode.node.teaser
+    - core.entity_view_mode.node.rss
   module:
     - node
     - taxonomy
diff --git a/core/profiles/demo_umami/config/install/views.view.taxonomy_term.yml b/core/profiles/demo_umami/config/install/views.view.taxonomy_term.yml
index fbd65897f3a3..1fd1315ab331 100644
--- a/core/profiles/demo_umami/config/install/views.view.taxonomy_term.yml
+++ b/core/profiles/demo_umami/config/install/views.view.taxonomy_term.yml
@@ -3,6 +3,7 @@ status: true
 dependencies:
   config:
     - core.entity_view_mode.node.card
+    - core.entity_view_mode.node.rss
   module:
     - node
     - taxonomy
-- 
GitLab


From 9026cd8227e7e35e6171a2e42647868168ab55a0 Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Sat, 19 Apr 2025 08:17:55 +0200
Subject: [PATCH 16/23] fix: prefer RSS if available and add explaination to
 the view_mode selection code

---
 core/modules/views/src/ViewsConfigUpdater.php | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php
index b0f25007a237..b4dc71eb9af6 100644
--- a/core/modules/views/src/ViewsConfigUpdater.php
+++ b/core/modules/views/src/ViewsConfigUpdater.php
@@ -385,14 +385,28 @@ public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $pre
       if (isset($display['display_options']['row']['options']['view_mode']) &&
         array_key_exists($display['display_options']['row']['type'], $row_types) &&
         $display['display_options']['row']['options']['view_mode'] === 'default') {
+
+        // When system.rss is already removed but a view is saved, we still need
+        // to try and set the view_mode to something more sane. But detecting
+        // if the view mode was always default, or default because it used the
+        // system.rss setting is hard. So if there is a default mode available
+        // it will use that.
+        // It would make sense to use any RSS view_mode if available, but that
+        // would mean 'default' can never be set as a view mode. That is an
+        // issue, therefor, if we have a default view mode available, we will
+        // use that.
         if ($previous_view_mode === NULL) {
           $view_modes = $this->entityDisplayRepository->getViewModes($row_types[$display['display_options']['row']['type']]);
           if (array_key_exists('default', $view_modes)) {
             return FALSE;
           }
 
-          $probable_view_mode = array_key_first($view_modes);
+          // If there is no default, the most likely view mode is RSS. If that
+          // is available we use that. Otherwise fall back to the first
+          // available.
+          $probable_view_mode = isset($view_modes['rss']) ? 'rss' : array_key_first($view_modes);
           $display['display_options']['row']['options']['view_mode'] = $probable_view_mode;
+          $changed = TRUE;
         }
         else {
           $display['display_options']['row']['options']['view_mode'] = $previous_view_mode;
-- 
GitLab


From 61fcf6d2d5e3f266bff1b7b8484925b5d3ac3d9f Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Sat, 19 Apr 2025 08:19:07 +0200
Subject: [PATCH 17/23] fix: prefer RSS if available and add explaination to
 the view_mode selection code

---
 core/modules/views/src/ViewsConfigUpdater.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php
index b4dc71eb9af6..86304904be0c 100644
--- a/core/modules/views/src/ViewsConfigUpdater.php
+++ b/core/modules/views/src/ViewsConfigUpdater.php
@@ -402,7 +402,7 @@ public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $pre
           }
 
           // If there is no default, the most likely view mode is RSS. If that
-          // is available we use that. Otherwise fall back to the first
+          // is available we use that. Otherwise, fall back to the first
           // available.
           $probable_view_mode = isset($view_modes['rss']) ? 'rss' : array_key_first($view_modes);
           $display['display_options']['row']['options']['view_mode'] = $probable_view_mode;
-- 
GitLab


From 31fec23b0802289ee1f27cb1d672c4f4869eb2d0 Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Sat, 19 Apr 2025 08:23:02 +0200
Subject: [PATCH 18/23] fix: prefer RSS if available and add explaination to
 the view_mode selection code

---
 core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
index 9f215ac3367e..cd324c9f8219 100644
--- a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
+++ b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
@@ -91,7 +91,7 @@ public function testUpdateRssViewModeWithoutKnownPreviousMode(): void {
     $updatedRowViewMode = $display['display_options']['row']['options']['view_mode'] ?? FALSE;
 
     // This should be the first node view mode since we have nothing else
-    $this->assertEquals('teaser', $updatedRowViewMode);
+    $this->assertEquals('rss', $updatedRowViewMode);
   }
 
   /**
-- 
GitLab


From a14c04ae35345521f33e909f93d0d585c8bd4425 Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Sat, 19 Apr 2025 10:41:18 +0200
Subject: [PATCH 19/23] feat: add test for when a view is saved that is also
 updates

---
 .../src/Kernel/ViewsConfigUpdaterTest.php     | 31 +++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
index cd324c9f8219..67b6c861ed1b 100644
--- a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
+++ b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
@@ -94,6 +94,37 @@ public function testUpdateRssViewModeWithoutKnownPreviousMode(): void {
     $this->assertEquals('rss', $updatedRowViewMode);
   }
 
+  /**
+   * Tests if onSave also updates the view.
+   */
+  public function testUpdateRssViewModeWithoutKnownPreviousModeOnSaveHandler(): void {
+    $this->installEntitySchema('node');
+    $this->installConfig(['text', 'field', 'node']);
+
+    $this->strictConfigSchema = FALSE;
+
+    /** @var \Drupal\views\ViewsConfigUpdater $view_config_updater */
+    $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class);
+
+    // Load the test view.
+    $view_id = 'views.view.test_display_feed';
+    $test_view = $this->loadTestView($view_id);
+    $display = $test_view->getDisplay('feed_1');
+
+    // Check the initial view mode.
+    $rowViewMode = $display['display_options']['row']['options']['view_mode'] ?? FALSE;
+    $this->assertEquals('default', $rowViewMode);
+
+    $test_view->save();
+
+    // Assert if the view mode was updated correctly onSave.
+    $display = $test_view->getDisplay('feed_1');
+    $updatedRowViewMode = $display['display_options']['row']['options']['view_mode'] ?? FALSE;
+
+    // This should be the first node view mode since we have nothing else
+    $this->assertEquals('rss', $updatedRowViewMode);
+  }
+
   /**
    * Tests the `needsRssViewModeUpdate` method.
    */
-- 
GitLab


From 60dba651855e58b33dc79ce630d7fbc522020c27 Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Sat, 19 Apr 2025 10:44:28 +0200
Subject: [PATCH 20/23] build: remove unused variable in
 ViewsConfigUpdaterTest.php

---
 core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
index 67b6c861ed1b..ceeb56a4787b 100644
--- a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
+++ b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
@@ -103,9 +103,6 @@ public function testUpdateRssViewModeWithoutKnownPreviousModeOnSaveHandler(): vo
 
     $this->strictConfigSchema = FALSE;
 
-    /** @var \Drupal\views\ViewsConfigUpdater $view_config_updater */
-    $view_config_updater = \Drupal::classResolver(ViewsConfigUpdater::class);
-
     // Load the test view.
     $view_id = 'views.view.test_display_feed';
     $test_view = $this->loadTestView($view_id);
-- 
GitLab


From b5c18c4882583b267ea8e0bd83f89f79f8cf2c1b Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Sat, 19 Apr 2025 13:27:39 +0200
Subject: [PATCH 21/23] fix: appearantly the config order matters when checking
 for config diff, which makes sense

---
 .../taxonomy/config/optional/views.view.taxonomy_term.yml       | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml b/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml
index eb6ad6ab3624..b34348136ad4 100644
--- a/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml
+++ b/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml
@@ -2,8 +2,8 @@ langcode: en
 status: true
 dependencies:
   config:
-    - core.entity_view_mode.node.teaser
     - core.entity_view_mode.node.rss
+    - core.entity_view_mode.node.teaser
   module:
     - node
     - taxonomy
-- 
GitLab


From 7e78a0e01c252b9bb25559397967d90f26488d1f Mon Sep 17 00:00:00 2001
From: Dave Long <24510-longwave@users.noreply.drupalcode.org>
Date: Tue, 6 May 2025 08:30:53 +0000
Subject: [PATCH 22/23] Apply 1 suggestion(s) to 1 file(s)

---
 core/modules/views/src/ViewsConfigUpdater.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php
index 86304904be0c..06a9e24f5ff2 100644
--- a/core/modules/views/src/ViewsConfigUpdater.php
+++ b/core/modules/views/src/ViewsConfigUpdater.php
@@ -393,7 +393,7 @@ public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $pre
         // it will use that.
         // It would make sense to use any RSS view_mode if available, but that
         // would mean 'default' can never be set as a view mode. That is an
-        // issue, therefor, if we have a default view mode available, we will
+        // issue, therefore, if we have a default view mode available, we will
         // use that.
         if ($previous_view_mode === NULL) {
           $view_modes = $this->entityDisplayRepository->getViewModes($row_types[$display['display_options']['row']['type']]);
-- 
GitLab


From 568b07ed11e5e94f79405f047c5cf99939993450 Mon Sep 17 00:00:00 2001
From: bjorn <bjorn@swis.nl>
Date: Tue, 13 May 2025 13:32:17 +0200
Subject: [PATCH 23/23] chore: add documentation to the 2 ViewsConfigUpdater
 methods

---
 core/modules/views/src/ViewsConfigUpdater.php | 22 +++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/core/modules/views/src/ViewsConfigUpdater.php b/core/modules/views/src/ViewsConfigUpdater.php
index 06a9e24f5ff2..5531d8934f85 100644
--- a/core/modules/views/src/ViewsConfigUpdater.php
+++ b/core/modules/views/src/ViewsConfigUpdater.php
@@ -367,10 +367,32 @@ public function processTableCssClassUpdate(ViewEntityInterface $view): bool {
     return $changed;
   }
 
+  /**
+   * Checks for views needing a default RSS view mode.
+   *
+   * @param \Drupal\views\ViewEntityInterface $view
+   *   The view entity.
+   * @param string|null $previous_view_mode
+   *   The previous view mode.
+   *
+   * @return bool
+   *   TRUE if the view has been updated.
+   */
   public function needsRssViewModeUpdate(ViewEntityInterface $view, ?string $previous_view_mode = NULL): bool {
     return $this->processRssViewModeUpdate($view, $previous_view_mode);
   }
 
+  /**
+   * Processes views and sets the default RSS view mode if necessary.
+   *
+   * @param \Drupal\views\ViewEntityInterface $view
+   *   The view entity.
+   * @param string|null $previous_view_mode
+   *   The previous view mode.
+   *
+   * @return bool
+   *   TRUE if the view was updated with a default RSS view mode.
+   */
   public function processRssViewModeUpdate(ViewEntityInterface $view, ?string $previous_view_mode = NULL) : bool {
     $changed = FALSE;
     $displays = $view->get('display');
-- 
GitLab