Problem/Motivation
Not having a Normalizer and Denormalizer to support Layout Builder
Steps to reproduce
When trying to export content as default content using any of the following commands
drush default-content:export node 1 --file=TARGET_PATH/content/node/homepage.yml
drush default-content:export node 2 --file=TARGET_PATH/content/node/blog-section.yml
Then the following fatal error shows up
Symfony\Component\Yaml\Exception\DumpException: Object support when dumping a YAML file has been disabled. in [error]
/var/www/html/dev/drupal80902/vendor/symfony/yaml/Inline.php:199
Stack trace:
#0 /var/www/html/dev/drupal80902/vendor/symfony/yaml/Dumper.php(97):
Symfony\Component\Yaml\Inline::dump(Object(Drupal\layout_builder\Section), 16)
#1 /var/www/html/dev/drupal80902/vendor/symfony/yaml/Dumper.php(153):
Symfony\Component\Yaml\Dumper->dump(Object(Drupal\layout_builder\Section), 9223372036854775803, 0, 16)
#2 /var/www/html/dev/drupal80902/vendor/symfony/yaml/Dumper.php(153): Symfony\Component\Yaml\Dumper->dump(Array,
9223372036854775804, 6, 16)
#3 /var/www/html/dev/drupal80902/vendor/symfony/yaml/Dumper.php(153): Symfony\Component\Yaml\Dumper->dump(Array,
9223372036854775805, 4, 16)
#4 /var/www/html/dev/drupal80902/vendor/symfony/yaml/Dumper.php(153): Symfony\Component\Yaml\Dumper->dump(Array,
9223372036854775806, 2, 16)
#5 /var/www/html/dev/drupal80902/docroot/core/lib/Drupal/Component/Serialization/YamlSymfony.php(22):
Symfony\Component\Yaml\Dumper->dump(Array, 9223372036854775807, 0, 16)
#6 /var/www/html/dev/drupal80902/docroot/core/lib/Drupal/Component/Serialization/Yaml.php(27):
Drupal\Component\Serialization\YamlSymfony::encode(Array)
#7 /var/www/html/dev/drupal80902/docroot/modules/contrib/default_content/src/Exporter.php(116):
Drupal\Component\Serialization\Yaml::encode(Array)
#8 /var/www/html/dev/drupal80902/docroot/modules/contrib/default_content/drush/default_content.drush.inc(59):
Drupal\default_content\Exporter->exportContent('node', '1', NULL)
#9 /usr/local/src/drush/includes/command.inc(422): drush_default_content_export('node', '1')
#10 /usr/local/src/drush/includes/command.inc(231): _drush_invoke_hooks(Array, Array)
#11 /usr/local/src/drush/includes/command.inc(199): drush_command('node', '1')
#12 /usr/local/src/drush/lib/Drush/Boot/BaseBoot.php(67): drush_dispatch(Array)
#13 /usr/local/src/drush/includes/preflight.inc(67): Drush\Boot\BaseBoot->bootstrap_and_dispatch()
#14 /usr/local/src/drush/drush.php(12): drush_main()
#15 {main}
Next Drupal\Component\Serialization\Exception\InvalidDataTypeException: Object support when dumping a YAML file has been disabled.
in /var/www/html/dev/drupal80902/docroot/core/lib/Drupal/Component/Serialization/YamlSymfony.php:25
Stack trace:
#0 /var/www/html/dev/drupal80902/docroot/core/lib/Drupal/Component/Serialization/Yaml.php(27):
Drupal\Component\Serialization\YamlSymfony::encode(Array)
#1 /var/www/html/dev/drupal80902/docroot/modules/contrib/default_content/src/Exporter.php(116):
Drupal\Component\Serialization\Yaml::encode(Array)
#2 /var/www/html/dev/drupal80902/docroot/modules/contrib/default_content/drush/default_content.drush.inc(59):
Drupal\default_content\Exporter->exportContent('node', '1', NULL)
#3 /usr/local/src/drush/includes/command.inc(422): drush_default_content_export('node', '1')
#4 /usr/local/src/drush/includes/command.inc(231): _drush_invoke_hooks(Array, Array)
#5 /usr/local/src/drush/includes/command.inc(199): drush_command('node', '1')
#6 /usr/local/src/drush/lib/Drush/Boot/BaseBoot.php(67): drush_dispatch(Array)
#7 /usr/local/src/drush/includes/preflight.inc(67): Drush\Boot\BaseBoot->bootstrap_and_dispatch()
#8 /usr/local/src/drush/drush.php(12): drush_main()
#9 {main}
Proposed resolution
Add a Normalizer and Denormalizer to support Layout Builder
Remaining tasks
PatchTest- Automated testing
- Review
- Release
User interface changes
- None
API changes
- None
Data model changes
Having a Normalizer and Denormalizer for layout builder. but not in Drupal core yet
When Drupal core has them we can switch to the core provided way. ( or could work right away without this fix )
#2942975: [PP-1] Expose Layout Builder data to REST and JSON:API
#2844452: Export configuration YAML strings as multiline
Issue fork default_content-3160146
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
berdirSee #2933777: REST/Serializer improvements in core/contrib make it less suitable for default_content use case, layout builder will require special integration as it stores objects, which I personally consider to be a bad idea. if it would store the values in an array format it would just work and also wouldn't require special integration in core rest/jsonapi either, at least not for the basics.
Comment #3
rajab natshahThank you Sascha
I will check that issue for sure
I'm testing the new branch 2.x
Thanks for your time on maintaining the Default Content module
Trying to do #3159243: Switch to Homepage node with Layout Builder
I may use 1.x or 2.x
Still testing both.
Comment #4
rajab natshah#2896971: Question about architecture
#3084161: Adding layout builder blocks in yml files
Comment #5
rajab natshahhttps://symfony.com/doc/3.1/components/yaml.html#dumping-multi-line-lite...
I do agree it's not clear
Serialized objects in YAML or unserialzed objects ( or arrays in YAML )
More research on this .....
Comment #6
andypostComment #7
rajab natshahThank you Andrey!!
I copied the link from your issue
Agrees with Sascha
Moving to use the supported 2.0.x branch <3
Still testing with
or
Comment #8
rajab natshahTested with Drupal 8.9.x core patch from #2844452: Export configuration YAML strings as multiline
[Yaml] add option to dump objects as maps #17728
https://github.com/symfony/symfony/pull/17728
--
https://github.com/symfony/symfony/pull/17728/files
Comment #9
rajab natshah#3084161: Adding layout builder blocks in yml files
Comment #10
berdirObjects shouldn't be exported, you're going down the wrong path. The correct fix is to normalize it as an array, just like the referenced core issue.
Comment #11
rajab natshahNoted;
Yesterday I had enabled the Better Normalizers
I use Better Normalizers only when I export. but not in the import
More testing and research
I feel that Default Content 2.0.x way is the best way
but the format of exported maybe not clear to read :/
No one need to read the nice formatted YAML or JSON !!
If the Default Content module is doing the export and import and the object for content is the same which expected
Thank you Sascha for correcting my direction
Ok Normalizers for serialized fields .. so they are treated like data or files
Comment #12
rajab natshahComment #13
rajab natshah#2942975: [PP-1] Expose Layout Builder data to REST and JSON:API
Comment #14
rajab natshahI couldn't run any drush dce or dcer commands
Until I made the following changes
in the attached patch file
Still I'm with Sascha's logic
Only saving my progress fixes in the patch
Tested the Export and the Import
with the following to ( export and import YAML files )
Comment #15
rajab natshahNow the right path is to normalize and dnormalize
What is the best format for
layout_builder__layout?normalizer
To me it feels the same serialized value in one data
denormalize
only to set it back to the layout_builder__layout
Comment #16
rajab natshahI think I have got it
In our custom modules
we can listen to the following events
and have our custom addon normalizer, denormalize
For example:
Class layoutBuilderSectionsNormalizerThe field_paragraphs is easy
But layout_builder__layout is hard
Excited for where the direction will go to the right direction
Comment #17
rajab natshahhttps://github.com/symfony/symfony/tree/3.1/src/Symfony/Component/Serial...
https://github.com/symfony/symfony/tree/4.1/src/Symfony/Component/Serial...
https://github.com/symfony/symfony/tree/5.1/src/Symfony/Component/Serial...
Comment #18
rajab natshahA better patch for a Layout Builder Normalizer and Denormalize.
Following your latest change of logic in code.
No need for any Drupal core patches.
When they commit the Layout Builder Normalizer class and functions to Drupal core we can switch to use them.
Comment #19
rajab natshahComment #20
rajab natshahComment #21
berdirall these create changes are not necessary. they are services and get their dependencies injected automatically.
yeah, this is the relevant part, that's the only thing that we need here.
Tests would be great though. Have a look at some of the normalizer tests that I added, if we would do something like that for layout builder, have a test that enables it, and then normalize and denormalize an entity that will make it much easier to get committed.
Comment #22
rajab natshahThanks Sascha for the quick review :)
I have updated the patch to remove not needed changes
Working on having the automated testing for LayoutBuilderNormalizerTest.php on the export/import part as you had listed
I had been testing with default_content_layout_builder.zip in the import part
Comment #23
mohammed j. razemComment #24
mohammed j. razemComment #25
joao sausen commentedBased on #22 I created a patch to fix reference on block_content when inserting custom blocks on layout builder.
There is no reference to the block_content uuid, so that patch creates a custom reference to it and make sure the id is correct when importing. It doesn't export the block with "drush dcer" because the block is not really referenced, so you need to manually get the block_content ids from the exported nodes and export them too.
Comment #26
Alexander Kalashnik commentedhttps://www.drupal.org/files/issues/2020-07-22/3160146-18.patch
Works fine for our situation.
Comment #27
rajab natshahChaning to use the #25 patch
#22 works too .. But #25 is better
Comment #28
elaman#25 is working well in my case
Comment #29
bonfil1 commentedHello, i've been working with #25 it works on D8 but when i try with D9 the import breaks while importing block_contents with a [InvalidArgumentException]
Property format is unknown.
Any idea if this is a D9 related issue or something in the module?
Comment #30
rajab natshahComment #31
rajab natshahComment #32
rajab natshahComment #33
nimoatwoodwayI adjust patch from #25 and adjust Exporter.php to respect dependencies of the layout builder components so those dependencies gets exported too when using
drush default-content:export-references.Don't now if this is the correct way of doing this and this ticket is the right place for it. Maybe it helps someone.
Comment #34
otarza commentedHey @nimoatwoodway,
I have just applied #33 and got following errors when importing just regular block_content without layout builder:
Comment #35
otarza commentedHey @nimoatwoodway,
Never-mind my previous comment, looks like I messed up my local install previously, I just fixed it and re-tested #33, it worked without problems, thank you!
Comment #36
heddnThis assumes we always have a derived plugin. But custom blocks that are exposed to LB don't always have this. NW for that.
Comment #37
heddnFixed #36.
Comment #38
berdirThe other section in the patch still has the same assumption that each block has a derivative ID, why not update that too?
Comment #39
s3b0un3t@heddn, your interdiff is incorrect.
Your patch remove the dependency management in Exporter.php file.
With your patch in #37, the "dcer" drush command no longer exports the inline blocks contributed in content.
Comment #40
rajab natshahPatch #37 is working well
I had a full testing round on export, and import on install of modules.
#3220899: Update the Normalizer and Denormalize patch for Layout Builder in the Default Content module
#3220904: Update Default Layout config for Varbase Landing page (Layout Builder)
#3220906: Update Default Layout config and Default Content in Varbase Blog for the Blog section
Comment #41
s3b0un3tPatch #33 modify Exporter.php to manage dependencies. Without the lines below, my install throw errors of unexisting block_content.
In your update of default contents in Verbase profile, you haven't "depends" property in your node content YAML file.
You cann't be sure, your content entities used in your node YAML file already exist.
Patch #35, add this lines in my local node YAML file (non exhaustive list) :
My blocks content (inline and reusable) are now created before to create node.
Comment #42
lisa.rae commented+1 for RTBC
Tested Patch #33 in conjunction with the following patches (FWIW both of these patches were applied before patch #33):
I had no problem importing and exporting both inline and regular custom block content.
Comment #43
emptyvoid commentedConfirming @lhridley series of patches.
Applied patches on both a Drupal 8 and Drupal 9 build.
Export from Drupal 8
Import into Drupal 9
Was successful!
Hope that all three patches are applied to a release someday!
Comment #44
nimoatwoodwayJust installed patch #37 to avoid warnings described in #36
No problems so far. Thanks!
Comment #45
abhijith s commentedTried applying patch #37.Also tried applying multiple patches as mentioned in the comment #42 .Both cases are not working.I'm still getting this error while exporting contents.
Comment #46
abhijith s commentedComment #49
johnzzonCreated a MR with #37 and the entity reference fix from #41. Export and reinstall works perfectly.
Comment #50
davidferlay commentedInstalled and tested patch from MR
Displaying /layout page of a node using LB content override and exported/imported using DC module throws an error:
Note that a Inline block content was added to layout
Comment #51
davidferlay commentedComment #52
grimreaperHi,
Uploading patch from MR 15 to be able to add it in Composer.
Comment #53
grimreaperHello,
I rebased the MR and made a small fix. When parsing layout builder blocks and a non-derivative plugin is found, an unused variable is not defined provoking PHP warnings.
Here is the patch for easier composer usage.
Comment #54
rajab natshahThank you, Florent for the patch in #53
Hoping that this issue get committed into the module.
Hoping for a release.
This will promote the Default Content module to be a standard tool for custom projects, modules, and profiles.
Comment #55
rajab natshahComment #56
rajab natshahComment #57
socialnicheguru commentedDoes this patch also fix, Layout Paragraphs Support?
Comment #58
nicholass@SocialNicheGuru in reply to #57 I tested this and no I don't think it fixes Layout Paragraphs Support
Comment #59
rajeshreeputra+1 for the RTBC.
Comment #60
andypostCan we get a basic test for that?
Comment #61
grimreaperHi,
For information: #3359137: Update inline block usage on import
Comment #62
eduardo morales albertiComment #63
crzdev commentedCurrent approach just avoids exception & skips "block serialized" approach, which is the default one; @see "\Drupal\layout_builder\Plugin\Block\InlineBlock::getEntity()":
So any serialized block dependencies are ignored, and is the first option when new non existing content block is used in layout builder, besides that approach just works with "inline_block" plugin variants & "InlineBlock instance" can be used instead in order to get it working per base class.
Other case where that should be managed as in layout builder you can mix entity field blocks and content blocks (content) into any display of exported content or its dependencies.
Also some entities like section library template may use same field type to store sections but in different field name, not "layout_builder__layout" but "layout_section", to manage that again "instance of SectionData" can be used instead to detect it.
So taking all use cases would be something like:
Besides changes going in this direction should be compatible with sites without layout_builder module enabled? Maybe all should be managed into import/export subscribers.
Working into patch/mr to manage at least first & second use cases.
Comment #64
crzdev commentedTo clarify main point, is not just about normalize / denormalize field but also include dependencies (exportContentWithReferences).
Comment #65
crzdev commentedAdded changes to MR;
Maybe "Drupal\block_content\Plugin\Block\Drupal\block_content\Plugin\Block" should be also supported (direct block content usage from core content block library). Also other possible use cases like commented into #63 -> 3.
Comment #66
cvalverp commentedThanks for patch #53, we have tested it in drupal 9.5. And it works correctly.
Comment #67
damienmckennaWould #2703607: drush command default-content-export-module-with-references help too?
Comment #68
drupalninja99 commentedThe content looks like it exports correctly but then I get this error on import:
I think the function is here in core/modules/layout_builder/src/Plugin/DataType/SectionData.php:
$value is coming in as an array not instanceof Section.
Comment #70
sickness29 commentedAdded test for new normalizer, let me know if I can help more, thanks
Comment #71
agentrickardLatest patch is working nicely on Drupal 10.3.6.. Both import and export of a Layout Builder page work as expected.
Comment #72
rajab natshahFacing the same issue as in #68, thanks, Jay, for reporting.
Comment #73
rajab natshahAttached a static
default_content--2024-11-13--3160146--mr-15.patchfile for MR15 from last changes to this point.to be used with Composer Patches
Comment #74
rajab natshahComment #75
rajab natshahThe patch in #53 is working
But, latest changes over the MR5, which was copied as a static file in #73 misses the order of first block ( Not working in the right way).
and all other blocks in the same Layout Builder get to be positioned in the wrong section or column
Comment #76
rajab natshahAttached a static default_content--2024-12-02--3160146--mr-15.patch file for MR15 from last changes to this point.
to be used with Composer Patches
Comment #77
rajab natshahComment #78
pbabin commentedNot sure if this is the correct place to report this. I'm also getting the
Object support when dumping a YAML file has been disabled.error. I saw that another post was closed that reported this error as being a duplicate. We're using layout-paragraphs (gasp) but that hasn't been the issue as we have been successful in the past in exporting and importing this data. We are actually still using the import functionality from our last export nearly a year or two ago but need to update our default content.I installed the most recent patch and the error occurs at the
$return = Yaml::encode($normalized)in the Exporter.php class. Since we have a lot of stuff being exported out I added the following to help me identify the issueAnd it looks like this is erroring out for us on a meta tag breadcrumb item we have on our page. I've included a screenshot from the xdebug if this might be helpful.
Any recommendations?
**Edit:
It's definitely the meta tag open graph webpage breadcrumb settings. I turned off the setting and I can export without that error. I have a workaround now but wanted to report this issue. Thank you @rajab_natshah for your work on the patch . . I would never have found this issue without seeing the files you touched.
Comment #79
pbabin commentedComment #80
rajab natshahPaul, it seems like you’re using a custom entity type, possibly a newly custom-coded one, but it doesn’t have Normalizer or Denormalizer support built in.
I realized this after Sascha's comment in #10
Comment #83
thejimbirch commentedThis is going to be important for some recipes in Drupal CMS and was referenced in #3493287: The default content importer should handle Layout Builder section data
Comment #84
berdirThanks for the reference. I would expect that this simplifies this issue a lot then, might be enough to normalize/export the structure into the correct format, without special import handling.
Comment #85
svendecabooterI'm having some issues with exporting Layout Builder layouts containing blocks of type 'inline_block'.
The patch in this issue allows them to be exported, and then imported via a Recipe (Drupal core behaviour).
However, in the export there is an explicit numeric 'block_id' and 'block_revision_id' property.
On the website I'm importing the content via a Recipe, the inline blocks don't necessarily receive the exact same numeric IDs.
Ideally the default content should reference UUIDs, instead of numeric entity IDs.
From my first tests, I'm able get this working with the patch in #3180702: Export block UUID with custom Layout Builder blocks (both the exporting & importing site need this patch applied).
Comment #86
crzdev commentedNot sure why latest changes was reverted, recover most relevant notes about important points written in #63 & #65,
please note that any existing exported default content generated without this logic, or previous version, may be incorrect as it is expectable and may be regenerated:
Current approach just avoids exception & skips "block serialized" approach, which is the default one; @see "\Drupal\layout_builder\Plugin\Block\InlineBlock::getEntity()":
So any serialized block dependencies are ignored, and is the first option when new non existing content block is used in layout builder, besides that approach just works with "inline_block" plugin variants & "InlineBlock instance" can be used instead in order to get it working per base class.
Other case where that should be managed as in layout builder you can mix entity field blocks and content blocks (content) into any display of exported content or its dependencies.
Also some entities like section library template may use same field type to store sections but in different field name, not "layout_builder__layout" but "layout_section", to manage that again "instance of SectionData" can be used instead to detect it.
So taking all use cases would be something like:
Reverted changes to MR;
Maybe "Drupal\block_content\Plugin\Block\Drupal\block_content\Plugin\Block" should be also supported (direct block content usage from core content block library). Also other possible use cases like commented into #63 -> 3.
Happily using those changes for months with Layout builder, VLSuite & Section library...
Comment #87
crzdev commentedAttach patch of that mentioned changes in case anyone wants to try, please also note that content provided by recipe & generated by default content will not use the same logic so it will fail so... maybe something has also to be done into "core recipe import content logic" to use similar or compatible strategies?
It should work fine using genenerated default content using these changes & creating content also with these changes (default content not core recipe content).
Comment #88
phenaproximaIt is worth mentioning that exporting layout data is natively supported by the default content exporter that is now in core and will be released in 11.3.0. (See https://www.drupal.org/node/3533854 for info about that.)
Comment #89
rajab natshahThanks, Adam, for your work on this.
Noticed that on the spot.
Switching to Drupal Core's new Export content method.
The code in Core is significantly cleaner, and the Default Content will no longer be necessary.
Comment #90
rosk0Noting that content export from core fails to export
pathautoconfiguration property for the node.Comment #91
ckaotikThanks @crzdev for the patch. In our case, we use both layout builder (works partially in core, requires patch in default_content) as well as paragraphs (supported by default_content, but not by core #3553119: Drupal content export does not support nested entities - Layout Builder inline blocks, paragraphs). Your patch saved us ;)
This duality is a bit troublesome, are there any plans to combine these efforts?
Comment #92
berdirThe plan is pretty simple: deprecate this module in favor of core after ensuring feature parity with the integrations and modules this supports. There are a few open issues, including one in ERR and one here to run our tests against the core API.
No plans on when that will happen, right now it would essentially be up to me (or someone else) to push it forward (in my case in my free time), if someone is willing to sponsor some time for that, reach out to me.