Problem/Motivation

When new view mode is enabled for the content type, for example, with UI, new view display always is copied from the "Default" display, meaning all the fields that are used in default display are added to the newly enabled display with the same settings. Later the new display can be adjusted to the needs.

Steps to reproduce

When the new view mode is enabled for the content type with recipes, no fields (components) are added to it by default. One needs explicitly provide the components with names and there settings. But sometimes, the names and settings are unknown in advance, and to be flexible and dynamic, it would be nice to have the config action that would copy the default view display, but for another view mode.

I believe there would be a lot of other use cases, for example, creating the config splits for lower environments, as they can be the same with only slight differences, etc.

Proposed resolution

Create config action that will duplicate config entity. For example:

core.entity_view_display.node.page.default:
  cloneAs: node.page.search_result

The config entity that is duplicated of course should be of the same type as the given config. This should be validated in the config action.

Release notes snippet

New config action to duplicate config entity. Recipe example usage:

core.entity_view_display.node.page.default:
  cloneAs: node.page.search_result

Issue fork drupal-3481238

Command icon Show commands

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

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

Comments

a.dmitriiev created an issue. See original summary.

phenaproxima’s picture

This seems like a reasonable and useful feature, so +1.

I'm not sure that duplicateIfNotExists makes sense, though; by definition, you can't duplicate a thing if the duplicate already exists.

I would suggest we make this as simple as possible, where the action only takes a string, which is the ID of the duplicate to create. So:

config:
  actions:
    core.entity_view_display.node.page.default:
      # Duplicates the default display, and gives it the ID of node.page.search_result.
      duplicate: node.page.search_result

In other words, this action should only be able to work on config entities that already exist.

phenaproxima’s picture

Also, I know this feature will be needed for Drupal CMS, so tagging as a Starshot blocker.

a.dmitriiev’s picture

Agree with #2.

phenaproxima’s picture

Issue summary: View changes

phenaproxima’s picture

Status: Active » Needs work
Issue tags: +Needs tests
phenaproxima’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
b_sharpe’s picture

Status: Needs review » Needs work

Up for discussion, but if I'm wanting to clone an existing config and it doesn't exist, I'd expect an error here rather than just not cloning as this could affect further actions.

phenaproxima’s picture

Title: Config action to duplicate config entity » Add a config action to clone a config entity
Status: Needs work » Needs review

I think I agree with you, on second thought. Adjusted!

b_sharpe’s picture

Status: Needs review » Reviewed & tested by the community

Nice! Tested and working as designed. RTBC

alexpott’s picture

Version: 11.0.x-dev » 10.4.x-dev
Status: Reviewed & tested by the community » Fixed

Committed and pushed 520019bb2fe to 11.x and 36a124b2f5e to 10.4.x. Thanks!

diff --git a/core/tests/Drupal/KernelTests/Core/Recipe/EntityCloneConfigActionTest.php b/core/tests/Drupal/KernelTests/Core/Recipe/EntityCloneConfigActionTest.php
index 5a712a60ab9..dd9472d81f7 100644
--- a/core/tests/Drupal/KernelTests/Core/Recipe/EntityCloneConfigActionTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Recipe/EntityCloneConfigActionTest.php
@@ -32,6 +32,9 @@ protected function setUp(): void {
     $this->createRole(['access user profiles'], 'test');
   }
 
+  /**
+   * Tests error if original entity does not exist.
+   */
   public function testErrorIfOriginalDoesNotExist(): void {
     $this->expectException(ConfigActionException::class);
     $this->expectExceptionMessage("Cannot clone 'user.role.nope' because it does not exist.");
@@ -39,6 +42,9 @@ public function testErrorIfOriginalDoesNotExist(): void {
       ->applyAction('cloneAs', 'user.role.nope', 'user.role.yep');
   }
 
+  /**
+   * Tests successful clone.
+   */
   public function testSuccessfulClone(): void {
     $this->container->get('plugin.manager.config_action')
       ->applyAction('cloneAs', 'user.role.test', 'cloned');
@@ -48,7 +54,10 @@ public function testSuccessfulClone(): void {
     $this->assertTrue($clone->hasPermission('access user profiles'));
   }
 
-  public function testNoConflictWithExistingClone(): void {
+  /**
+   * Tests no error is thrown when an entity with the same ID already exists.
+   */
+  public function testNoErrorWithExistingEntity(): void {
     $this->createRole(['administer site configuration'], 'cloned');
 
     $this->container->get('plugin.manager.config_action')

Fixed on commit.

  • alexpott committed 36a124b2 on 10.4.x
    Issue #3481238 by phenaproxima, a.dmitriiev, b_sharpe, alexpott: Add a...

  • alexpott committed 520019bb on 11.x
    Issue #3481238 by phenaproxima, a.dmitriiev, b_sharpe, alexpott: Add a...

  • alexpott committed 09e44ad0 on 11.x
    Issue #3481238 follow-up by phenaproxima, a.dmitriiev, b_sharpe,...
wim leers’s picture

Issue tags: +Needs change record

Are we not doing change records to announce the availability of this, and in which version it's available? 🤔

(Very cool BTW!)

thejimbirch’s picture

Needs to be added to the docs also.

phenaproxima’s picture

Issue tags: -Needs change record

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

thejimbirch’s picture