Problem/Motivation

Full disclosure: I'm not sure if this problem is caused by something missing in the content migration or a problem with the module.

On a site we migrated from D7 the Layout Paragraphs functionality works correctly with nodes that are created from scratch post migration. However, when we edit the layout added to a migrated node the layout doesn't work completely correctly - the initial save is fine, but when the content is edited again the paragraphs which were located in a layout are moved into the "disabled items" list.

Debugging the problem I've found that the "behavior_settings" data of the migrated nodes is slightly different, specifically they're missing the "parent_delta" attribute. Could this be the cause?

Steps to reproduce

* Migrate data from a D7 site to D9.
* In the paragraph field, add a layout paragraph.
* Add a text paragraph to each column in the layout.
* Save the node.
* Edit the node.

Expected results:
* The paragraphs will be in the same positions they were in prior to saving the display.

Actual results:
* The paragraphs positioned in the layout columns/regions will be moved into the "disabled items" region.

Proposed resolution

Work out the cause, whether it's a problem with the migration or a bug in Layout Paragraphs (or something else?).
Fix it, or document how it was fixed.

Remaining tasks

Work out the cause of the problem.
In the case of a migration bug, document the solution.
In the case of a module bug, provide a fix.

User interface changes

TBC

API changes

TBC

Data model changes

TBC

Comments

DamienMcKenna created an issue. See original summary.

damienmckenna’s picture

I've confirmed that the migrated node does not have a parent_delta value defined on each paragraph whereas the freshly created node does. I'll continue digging.

damienmckenna’s picture

I then looked at $uuid_map and realized that the migrated nodes don't have a record that matches the parent_uuid of the paragraph within the layout, e.g.:

$uuid_map:

Array
(
    [0985a130-e8a3-4c9a-9e85-e847be70ffb0] => 0
    [693380c8-8272-48e0-bf8c-095849c4944a] => 1
    [4a7ed670-cbdb-436a-bd04-0cd3a6c3e96e] => 2
    [605e9413-fbed-4ee8-aa44-ec2a3b3edae4] => 3
    [f4b170bb-63a9-47d9-a474-7b57b4e2d8d1] => 4
)

$behavior_settings['layout_paragraphs']:

Array
(
    [region] => left
    [parent_uuid] => d7d0d679-274b-41b6-9e9f-4b40503caa18
    [layout] => 
    [config] => Array
        (
        )

)

It's worth noting that I don't see a record in paragraphs_item with a uuid of "d7d0d679-274b-41b6-9e9f-4b40503caa18".

That's kinda weird.

On the freshly created node the parent_uuid value points to a paragraph that *does* exist.

damienmckenna’s picture

I did notice that the migrated node has the langcode set to "und" whereas the freshly created node's langcode is "en", I wonder if this is the problem?

damienmckenna’s picture

Status: Active » Closed (works as designed)

Yes - updating node_field_data, node_revision_field_data, node__field_content (the paragraphs field) and node_revision__field_content to set the langcode to "en" instead of "und" did indeed fix the problem. So we'll go back and fix the content migration.

Hope this brain dump will help others who might run into the problem.

greenhorn’s picture

Hi @DamienMcKenna,

As I have read, you have already performed a migration with layout paragraphs. I've been struggling for a while and currently have no idea how to migrate content to the layout paragraph. Is it asking too much if I ask how you did it?
I would be very grateful to you for a short help.

damienmckenna’s picture

We didn't migrate content to match Layout Paragraphs, we had problems that migrated content which used a Paragraphs field couldn't be modified using Layout Paragraphs, just regular paragraphs.

To migrate into Layout Paragraphs you would have to create a new paragraph that defined the layout and then assign other paragraphs to this in the behavior section of the paragraphs field. Paragraphs stored in Layout Paragraphs are not stored as nested entities, they're stored as top level items in the same entity reference revisions field and then extra configuration data in the behaviors section controls the placement in the layouts.

You might want to create some example data and examine how the data is stored in the database, doing that was how I worked out the source of my problem here.

Hope that helps a bit.

greenhorn’s picture

Many thanks for the quick reply also on Sunday. That's more than I expected. Thanks very much!
I also noticed that layout paragraphs are not nested.
I currently do not know how to create this paragraph in the migration. I have the paragrah with machine_name "layout_sections".
Available layouts are "layout_onecol" or "layout_twocol"
So basically I know how to migrate paragraphs but I'm being a bit stupid here and I hope for your help.
Here my code...

id: article_paragraph_layout_sections
label: Migriert paragraph_layout_sections
migration_group: xlsx_article
migration_tags:
  - node
  - article
  - paragraph
  - layout
source:
  plugin: spreadsheet
  file: sites/default/files/migrate/Newsroom_BdB_Data_IA_20220728-copy.xlsx
  worksheet: 'allPagesWithTAGs'
  origin: A12
  header_row: 11
  columns:
    - id
  row_index_column: 'rowNum'
  keys:
    id:
      type: integer
      size: big

process:
  type:
    plugin: default_value
    default_value: "layout_sections"

#  how do I set the layout here?
#  Available layouts are "layout_onecol" or "layout_twocol"
#  or do we have to do that in node migration
#  if yes how

destination:
  plugin: entity_reference_revisions:paragraph
  default_bundle: layout_sections

migration_dependencies:
  optional:
    - article_node

and in article_node

  prepare_field_content:
    - plugin: migration_lookup
      migration:
        - article_paragraph_layout_sections
      source: id

  field_content:
    - plugin: sub_process
      source:
        - '@prepare_field_content'
      process:
        target_id: '0'
        target_revision_id: '1'

I would appreciate an answer.
Many thanks!

norman.lol’s picture

I think the answer is somewhat in this migrate_plus issue #3440904: Process plugin: build an array from source, destination, pipeline where an array_template plugin got added.

Following sample is not layout paragraphs, but for layout paragraphs it's also just behavior_settings in the, see more samples in the issue mentioned above. This can also be populated dynamically of course.

Here two behavior_settings for a paragraph get set:

id: paragraphs_text
label: 'Import body fields'
description: 'Import body fields into text paragraphs'
migration_group: pages

destination:
  plugin: entity_reference_revisions:paragraph
  default_bundle: text

process:
  text_text/value: 'de body'
  text_text/format:
    plugin: default_value
    default_value: basic_html
  langcode:
    plugin: default_value
    default_value: de
  uid:
    plugin: default_value
    default_value: 1
  behavior_settings:
    -
      plugin: array_template
      template:
        paragraph_width:
          width: narrow
        paragraph_vertical_spacing:
          top_spacing: large
          bottom_spacing: large
    -
      plugin: callback
      callable: serialize