Problem/Motivation
Drupal CMS is going to need the ability to ship default content that includes layout section data. You can export such content from the Default Content module, provided you have #3160146: Add a Normalizer and Denormalizer to support Layout Builder applied to it, but you cannot import it using \Drupal\Core\DefaultContent\Importer because it doesn't know how to handle section data that has been downcast to an array, even though Layout Builder itself explicitly supports converting section data to and from arrays.
Steps to reproduce
Apply the aforementioned patch to default_content, and export a node (or anything) that contains a layout section. The export will succeed. Put that exported content into a recipe and try to apply the recipe, and it will fail with this error: Value assigned to "section" is not a valid section .
Proposed resolution
Change \Drupal\layout_builder\Plugin\DataType\SectionData::setValue() to allow arrays, and call Section::fromArray(). It has code to explicitly reject any value that is not already a Section object, and that wouldn't go away; it would simply be able to gracefully handle an array, and assume that it was a downcast Section object.
Remaining tasks
Implement with test coverage, and land this in 11.1.0-rc2. In Slack, @catch felt (informally) that this could land in RC since it's an internal change and blocks a stable release of Drupal CMS.
User interface changes
None.
Introduced terminology
None.
API changes
None.
Data model changes
None.
Release notes snippet
TBD, probably none.
Issue fork drupal-3493287
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
Comment #2
longwaveAs mentioned SectionData has this:
This was added in #2926914-30: Rewrite \Drupal\layout_builder\Section to represent the entire section, not just the block info with no discussion or review comments so I'm not sure why it was done, but it seems feasible to extend this method to accept an array and call
Section::fromArray()if necessary.To me that is preferable to adding a special case for a module to core code.
Comment #5
phenaproximaFor the record, I like @longwave's approach better, but opening two MRs anyway just in case there was some reason why the type check was added in https://www.drupal.org/comment/12373836. In any event, I didn't remove the type check; just allowed it call Section::fromArray() if it's given an array to work with.
Comment #6
phenaproximaComment #7
phenaproximaOK, I have thought about it a bit and @longwave's way is about 1,000 times better than my proposed approach. Even if this doesn't land in time, and I have to polyfill it, it's a lot easier to override/decorate a typed data plugin that forking the entire default content importer.
Comment #9
alexpottComment #10
phenaproximaTest written!
Comment #11
phenaproximaComment #12
alexpottAdded some comments to the MR.
Comment #13
rajab natshahI hope #3160146: Add a Normalizer and Denormalizer to support Layout Builder is supporting the Recipes default content import.
(Tested with a playground profile. did not work.) The MR works only with a module, not a recipe.
A Normalizer and Denormalizer in Drupal Core are essential for sections and blocks.
Comment #14
alexpottThis looks great - a simple fix that allows core's default content to import content created by the default content module plus the layout builder patch from #3160146: Add a Normalizer and Denormalizer to support Layout Builder
Comment #15
phenaproximaComment #16
alexpott@tim.plunkett wants to have a look at this before we merge it.
Comment #17
tim.plunkettI agree with @longwavein #2, this would have been a lot more helpful if #2926914-30: Rewrite \Drupal\layout_builder\Section to represent the entire section, not just the block info had explained how I ended up with this. I definitely recall wrestling with TypedData and the inherent magic-ness of setValue(), and I think I was just trying to save my sanity by having it blow up if something else was passed in.
The change here is sound, and the tests look good.
Comment #18
alexpottCommitted and pushed a44cf1ef008 to 11.x and 5b1a9182e9f to 11.1.x and 0a5101f68df to 10.5.x and d7f5dbc09cd to 10.4.x. Thanks!
As this unblocks Drupal CMS and after discussion with @longwave agreed to put this in 11.1.x - since it applies also put it in 10.4 and 10.5
Comment #23
thejimbirch commentedThis should be in the default content system, not the recipe system.
Comment #24
greencow commentedHi folks, great work on getting this fixed. I'm using this successfully in my development environments along with the patch in #3160146: Add a Normalizer and Denormalizer to support Layout Builder to propagate layouts.
I've run into an issue that may or not be related. If the original content type for which the layout builder is enabled is imported into a new environment, the layout builder setting is ignored. So I find myself having to manually enable the layout builder across environments. Once I do, then the import process above will work and I can see my custom layouts. Is this a bug perhaps?