Problem/Motivation

There is currently no way to add or alter components in a layout via a recipe. We should have a config action that allows recipe to add or edit components in a layout.

Proposed resolution

Created new ConfigSectionListTrait with a config action for adding a new component.

An example provided here:

config:
  actions:
    dashboard.dashboard.welcome:
      addComponentToLayout:
        section: 0
        position: 4
        component:
          region:
            layout_twocol_section: 'second'
          default_region: content
          configuration:
            id: dashboard_text_block
            label: 'My new dashboard with weight from a plugin'
            label_display: 'visible'
            provider: 'dashboard'
            context_mapping: { }
            text:
              value: '<p>My new dashboard with weight from plugin</p>'
              format: 'basic_html'

The config action would get a position, and will calculate the weight based on that, and recalculate the weights of the components after this one.
The region is a map of layout => region in case we don't know if the given section has a concrete layout.
A default_region can be given in case the section layout is not on that map.

Remaining tasks

Review.

User interface changes

None.

Introduced terminology

None.

API changes

API addition.

Data model changes

None.

Release notes snippet

TBD.

CommentFileSizeAuthor
#21 3475115-nr-bot.txt2.72 KBneeds-review-queue-bot

Issue fork drupal-3475115

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

thejimbirch created an issue. See original summary.

quietone’s picture

Version: 11.0.x-dev » 11.x-dev

penyaskito made their first commit to this issue’s fork.

penyaskito’s picture

Issue tags: +Barcelona2024

Thought that this could fit in SectionListTrait, but timplunkett pointed out that this would only make sense in config based section lists, so will be its own trait.

plopesc’s picture

Great step forward @penyaskito. Really looking forward to have this in core!

Tried to test it locally to integrate it with navigation module with no luck. Probably I missed one or more steps.

Steps I followed:

  • Clone the branch
  • Add use ConfigSectionListTrait; to NavigationSectionListStorage
  • Implement uuidGenerator() method
  • Clear cache at least once
  • Execute ddev . php core/scripts/drupal recipe modules/my_recipe
  • Get the error: The "addComponent" plugin does not exist. Valid plugin IDs for Drupal\Core\Config\Action\ConfigActionManager are: ....

The recipe.yml used for testing was like this:

name: Navigation Test Recipe
type: Examples
description: 'Adds a block to navigation.'
install:
  - navigation
config:
  actions:
    navigation.block_layout:
      addComponent:
        section: 0
        position: 1
        value:
          uuid: 30000000-0000-1000-a000-000000000000
          id: 'navigation_menu:content'
          label: Content From Recipe
          label_display: 1
          provider: navigation
          region:
            content: 'content'
          default_region: content
          level: 1
          depth: 2

Could you please indicate the steps I missed?

Thank you!

penyaskito’s picture

Apparently I was wrong and looking at \Drupal\Core\Config\Action\Plugin\ConfigAction\Deriver\EntityMethodDeriver::getDerivativeDefinitions, ActionMethods are only valid for ConfigEntityTypeInterface implementations, so Navigation will need to declare its own ConfigAction plugin.

So this will only be useful as is for LayoutBuilderEntityViewDisplay in core, and of course contrib.

penyaskito’s picture

Issue summary: View changes
Status: Active » Needs review

MR is ready for review. We might want more test coverage for the weight recalculation, but I'd prefer to get feedback on the direction.
I'm not sure how are we testing config actions. Ideally we would have test recipes instead of just testing the method.

We might want to implement this in LayoutBuilderEntityViewDisplay, but not sure if part of the same MR.

phenaproxima’s picture

Issue tags: +Starshot blocker

Drupal CMS is going to need this, tagging accordingly.

phenaproxima’s picture

Status: Needs review » Needs work

Kicking back for addressing my remaining feedback. :) But I think this is a great start on a helpful action, and I'd really like to see it in core.

penyaskito’s picture

Didn't remove the changed I had before yet.

This means that setSection needs to change its visibility from protected to public in SectionListTrait.

Not sure if I implemented the deriver right, but this worked for me with a slightly different version of the previous recipe:

config:
  actions:
    dashboard.dashboard.test:
      addComponent:
        section: 0
        position: 4
        component:
          uuid: 01929a0b-056f-72c1-b390-c9bdc3f6fd5e
          id: dashboard_text_block
          label: 'My new dashboard with weight from a plugin'
          label_display: 'visible'
          provider: 'dashboard'
          region:
            layout_twocol_section: 'second'
          default_region: content
          context_mapping: { }
          text:
            value: '<p>My new dashboard with weight from plugin</p>'
            format: 'basic_html'

penyaskito’s picture

This needs better test coverage.

We only cover adding new components. I'd expect we want a separate action for adding multiple components, and a separate one of editing existing components, as @phenaproxima said it would be better to have them separated.
Not sure if we should cover these here or in follow-ups.

gábor hojtsy’s picture

The MR only seems to add the "add layout component" action, so I think its far that it only has tests for that. @phenaproxima indicated that these improvements to the tests would be good, that still looks like needs work:

  • We need to be sure the region stuff works as expected, including when the default region is used, or the region can't be resolved.
  • We need to be sure the position stuff is figured out correctly, every way it could be passed in.
  • We need to be sure that the additonal key is preserved if passed.
  • The test...isn't using config actions. That obviates the entire point of this MR. We need to test that we can accomplish the addition of the component using config actions. (We don't need to use a recipe, but we probably need ConfigActionManager::applyAction(...).
gábor hojtsy’s picture

Title: Provide a Config Action to add/edit a component in a layout » Provide a Config Action to add a component in a layout

Reached out to phpstan folks. Learned that #3484349: Add missing @return types for StringTranslationTrait::formatPlural() and ::getNumberOfPlurals() is in the way, until that lands, the phpstan baseline needs updating in the MR.

pameeela’s picture

phenaproxima’s picture

Discussed with @penyaskito and we agreed that this is nice to have, and would accelerate Drupal CMS's dashboard work track, but is not a stable blocker.

pameeela’s picture

Tagging as a target so it's on the radar somewhere, it's intended to be used for nice-to-haves.

penyaskito’s picture

Status: Needs work » Needs review

Added moar test coverage as requested.

The only remaining comments are about reusing the existing array, but don't think creating a new one and copying every key value (as we don't know the specific block schema) would make it more clear.

gábor hojtsy’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +Needs change record

The added test coverage looks good IMHO. This part needs a change record I think?

diff --git a/core/modules/layout_builder/src/SectionListTrait.php b/core/modules/layout_builder/src/SectionListTrait.php
index 7a049dec6c40cabdf30343afedd0477d81e4786d..b55fe12ca5432871741e3b26e116d8634cd11148 100644
--- a/core/modules/layout_builder/src/SectionListTrait.php
+++ b/core/modules/layout_builder/src/SectionListTrait.php
@@ -54,7 +54,7 @@ public function getSection($delta) {
    *
    * @return $this
    */
-  protected function setSection($delta, Section $section) {
+  public function setSection($delta, Section $section) {
     $sections = $this->getSections();
     $sections[$delta] = $section;
     $this->setSections($sections);
thejimbirch’s picture

Is it possible for 2 change records? We have been adding them for new and altered config actions. Something like:

Recipes can now add a component in a Layout Builder layout using the addComponent config action

needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new2.72 KB

The Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

rajab natshah made their first commit to this issue’s fork.

thejimbirch’s picture

penyaskito’s picture

Status: Needs work » Needs review

This should be ready, we still need the change record for making public setSection.

penyaskito’s picture

penyaskito’s picture

Assigned: Unassigned » penyaskito
Status: Needs review » Needs work
penyaskito’s picture

Status: Needs work » Needs review

Back to NR.

penyaskito’s picture

Assigned: penyaskito » Unassigned
phenaproxima’s picture

Status: Needs review » Needs work

Looks great. I have basically no complaints about the action itself. My only outstanding issues:

  • Needs two change records before I can RTBC: one to document the action itself, the other to mention the publicizing of setSection.
  • The test is a bit repetitive and could be refactored for clarity by using a data provider.

I had a couple of minor nitpicks as well. But this doesn't feel far off to me.

thejimbirch’s picture

Draft change record for the action exists: https://www.drupal.org/node/3519491

Can you add a little more detail with what your want with "the other to mention the publicizing of setSection."? I can try to add it.

thejimbirch’s picture

phenaproxima’s picture

Pretty simple - I think we just want to mention that \Drupal\layout_builder\SectionListTrait::setSection() is now a public method and will be available on every class that uses SectionListTrait.

penyaskito’s picture

Issue summary: View changes
Status: Needs work » Needs review

Fixed change record and IS with a (valid and tested) example.

penyaskito’s picture

Issue tags: -Needs change record

And added missing change record for SectionListTrait::setSection() is now a public method

penyaskito’s picture

Issue tags: +11.2.0 release target

I'd hope to have this on 11.2 for any further development around providing/adjusting dashboards in Drupal CMS for the next months.

phenaproxima’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +Needs followup

This looks great to me. There are a couple of minor gaps here, such as:

  • Testing that a preassigned UUID is preserved.
  • Testing that the action only works with config entities that implement SectionListInterface, and is not found for any other entity type (i.e., coverage of the deriver).

Since I agree that we'd really like this in 11.2, I think it is okay to add that coverage in a follow-up rather than hold this issue up any longer. Tagging for that, but otherwise...ship it.

larowlan’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs documentation, +Needs subsystem maintainer review

Looking good, asked a question of the maintainers about the API addition.
It would be good to add some docs to the action. We have some example YML in comments above - something like that would be really valuable.

penyaskito’s picture

#36 Created the test for the first point, added follow-up #3522807: Add unit test for Drupal\layout_builder\Plugin\ConfigAction\Deriver\AddComponentDeriver for the second one.

Added phpdoc with example and docs for the config action.

penyaskito’s picture

Status: Needs work » Needs review
danielveza’s picture

MR is looking good. I've done a couple of code reviews and left a few minor comments. re: #37 I'm ok with the API change as outlined in the MR, but I'll leave the tag for now just in the case the other LB maintainers want to weigh in.

phenaproxima’s picture

Status: Needs review » Reviewed & tested by the community

Couple minor points but I'm happy with this. If the subsystem maintainer signs off, ship it. Call this a soft RTBC.

penyaskito’s picture

All feedback resolved. Only detail is confirming that we're fine leaving #3523019: `\Drupal\layout_builder\Section::setComponent` should verify the region in that layout exists as a follow-up, as I don't think we should do that in the action itself.

larowlan’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: -Needs subsystem maintainer review

Credits

larowlan’s picture

Status: Needs work » Reviewed & tested by the community

Didn't mean to change status

  • larowlan committed 66d8b1b5 on 11.x
    Issue #3475115 by penyaskito, gábor hojtsy, thejimbirch, phenaproxima,...

larowlan’s picture

Status: Reviewed & tested by the community » Fixed

Committed to 11.x
Published both of the change records
Thanks all

Status: Fixed » Closed (fixed)

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