Hi,
I created issues in the two widely used clone modules, which are both affected by the same problem:
Cloning a node containing a layout paragraph results in broken structure as the contained paragraphs are moved into "Disabled Items" region.
See
- Entity Clone: #3218223: Cloning Entities with Layout Paragraphs breaks structure and moves subparagraphs into Disabled Items
- Quick Node Clone: #3218222: Cloning Entities with Layout Paragraphs (1.x) breaks structure and moves subparagraphs into Disabled Items
Does the maintainer or anyone else have an idea
a) why this happens
b) where and how this could be fixed
c) how it affects 2.x?
Thank you very very much in advance!
| Comment | File | Size | Author |
|---|---|---|---|
| #15 | 3218226-15.patch | 12.75 KB | justin2pin |
Issue fork layout_paragraphs-3218226
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
anybodyThe two hidden fields in each layout paragraph have the wrong value in the clone. How are they filled typically?
For example, all paragraph contents have:
layout-paragraphs-region="_disabled"
And I found this code mentioning the "replicate" module in layout_paragraphs.module, line 83:
on the one hand I think this should then work with entity_clone (but doesn't) and on the other hand it won't work for quick_node_clone as it prefills the clone form with copies. So we'd need a different strategy there?
Replicate seems pretty dead for Drupal 8 / 9?
Comment #3
anybodyOk to me it seems that Paragraph::createDuplicate() which is for exmaple used in Quick Node Clone does NOT clone behaviourSettings, is that correct?
While Layout Paragraphs uses behaviourSettings to store this information. Furthermore would the parent_uuid have to be updated after getting the $paragraphs->createDuplicate() happened?
Comment #4
anybodyYes that was very close to the reason :)
Indeed createDuplicate() also duplicates the Behaviour Settings, but createDuplicate() also correctly renews UUIDs so that parent_uuid values are pointing to the old paragraphs and have to be updated!
So what has to be done here is to save the old paragraph UUIDs from before the cloning and after the cloning and replace the old ones with the new ones.
I created example working code directly in Quick node clone, see https://www.drupal.org/project/quick_node_clone/issues/3218222#comment-1...
But I guess it shouldn't be Quick Node Clone specific. What we need is a hook on Entity::createDuplicate() (e.g. Paragraph::createDuplicate()) which provides us with the old and the duplicate paragraph entity and put the parent_uuid logic there.
Comment #5
justin2pin commented@Anybody - thanks for digging into this. I think the root issue is #3040556: It is not possible to react to an entity being duplicated -- as you pointed out in the comments on that issue. Currently there isn't a consistent way to respond to an entity being duplicated. The goal in layout_paragraphs_paragraph_presave() is provide a work-around that addresses the broadest set of use-cases possible, but obviously it's still not broad enough :).
Also, I'm surprised Quick Node Clone isn't triggering hook_paragraph_presave().
Regardless, we need to get this working for both 1.0.x and 2.0.x. We're focussing exclusively on the 2.0.x branch at this time, but am happy to back-port a solution, once we have one. Also happy to review patches for 1.0.x, and a fix for this would definitely be applied to 2.0.x. Thanks again.
Comment #6
anybodyHi @just2pin and thank you very much for your fast reply!
The reason why Quick Node Clone does not call hook_paragraph_presave() is that it only prefills the form with the cloned values, but does not save them yet. It only creates the copies without calling ->save() - which is a quite helpful way to create entity copies. Entity clone creates the clone first. Anyway it has the same problems as written above, I didn't test why as I like the Quick Node Clone strategy.
So what would be your suggestion on how to proceed here? I guess for Entity clone it might be solvable by debugging the presave hook. For Quick Node Clone I have no clue until #3040556: It is not possible to react to an entity being duplicated is fixed. But as you know the layout_paragraphs code better than me, it would be very helpful if you could add some information if the Quick Node Clone patch won't work for 2.x what to change.
Any further ideas welcome! :)
Comment #7
nvakenWe we're experiencing the same issues. To make sure we're not creating another workaround for this issue, I've been inspecting `layout_paragraphs_paragraph_presave()` and why it does not work on entity_clone.
As far as I can tell, entity_clone is doing the following;
I'm not entirely sure why the presave hook would work in the replicate module, since the parenting node will probably never have new references until the references have been created and re-referenced in the node and the node has been saved... Still not sure if I'm on the right track here. Will try to find time to investigate further.
Comment #8
anybodyAs @justin2pin wrote in #5 we should focus on 2.x version and I think we don't need a backport, as 1.x can hopefully be deprecated with a full and clean upgrade path to 2.x!
So let's use the information from above for 2.x and ensure cloning will work there, at least with any cloning module.
Comment #9
andrewmriv commentedI created a fix for the Entity Clone module.
When cloning using Entity Clone, it causes
hook_ENTITY_presave()to trigger in thelayout_paragraphs.modulefile. This patch adds a check to see if$behavior_settings['layout_paragraphs']['clone']is TRUE. If it is, it skips the usual steps that take place when saving a layout paragraph node.This patch is required for the solution in #5 to work.
Tested with 8.x-1.x of Entity Clone and 8.x-1.x of Layout Paragraphs.
If I get the chance, I will also test with with 2.x of Layout Paragraphs.
Edit - If you are not using the Replicate module, look at #23 instead of the patch in this comment.
Comment #10
anybodyGREAT work @andrewmriv!! :)
Yes would be great if you could test that for 2.x and create a merge request for that. 1.x patch is ready for review I guess?
Comment #11
justin2pin commentedFirst, thanks for all the work on this. Great to see a working patch for the 1.x branch.
I think ultimately we need a solution that is completely native to Layout Paragraphs, and doesn't require a specific patch to other modules. With that in mind, I created a new service – LayoutParagraphsCloneService – to help (a) determine if we are currently cloning content, and (b) re-map UUIDs when we are.
Patch is attached. Feedback would be greatly appreciated.
Comment #13
justin2pin commentedRerolled to fix for coding standards (two unnecessary use statements).
Comment #15
justin2pin commentedOne more time, now correctly including the new file :) ...
Comment #16
anybodyHi @justin2pin,
thank you very much for your patch! This is quite complex.
How do we use it? Does it work with Quick Node Clone and Entity Clone?
Or is it about duplicating single paragraphs and not the parent entity / node?
Comment #17
davisbenThe patch isn't applying anymore. Here's a reroll.
Comment #18
anybodyClarified the title for 2.x
Comment #21
realityloop commentedPatch no longer applied so I rerolled it as a merge request instead.
Comment #22
realityloop commentedThis currently causes the Drupal site to crash when enabling the module (my MR diff)
Comment #23
andrewmriv commentedIf anyone was using my 1.x solution from #9, this new patch also includes a fix. It was a 1 line change in 3247496: Cannot place existing paragraphs into new sections without saving new section first..
I only recommend this patch if you are using Entity Clone and not Replicate as it has not been tested with that module.
Comment #24
hudriDid some manual tests of justin2pin's patch from #15 (using 2.0.0-beta9):
You just need to add the patch in the composer.json, the
presavehook will handle everything, the cloning modules don't need any modifications.parent_idon clone source after cloning)Comment #25
anybodyThank you for wrapping this up so great @hudri! So should we set #15 RTBC? Or does it need a reroll against latest 2.0.x-dev? Then it would be cool if someone could do this with an interdiff.
Nice to see this close to be fixed! :)
Comment #26
justin2pin commentedAfter working more on this I think we need to go in a different direction. Until #3040556: It is not possible to react to an entity being duplicated is resolved, there just isn't a good universal way to determine if an entity (and its reference revisions field) is being cloned. For now, we're going to implement hooks (or subscribe to events) for major clone/replicate modules. I'm going to add a separate feature request issue to track this work.
Comment #27
anybody@justin2pin: This is a bit off-topic, but please see my comment #22 in #2910237: Deprecate Quick Node Clone in favour of Entity Clone I don't know where, who and how, but as you said in #26 the current situation isn't good for Drupal 8+ at all. Several cloning modules exist, but none of them is able to handle all kind of entities. For Drupal developers it's bad, for Drupal customers this is a mess in UX, so it would be nice if we could push things forwards somewhere ;)
Now BTT! I think #26 is the right way to go for layout_paragraphs until there is one clone module to rule them all.
Comment #28
yonailoI have tested patch #15 and it seems that it does not work well with translations.
I use quick_node_clone. After cloning, the cloned node is good but its translations are not.
Any clue ? Has anyone tested #15 with translations ?
Comment #30
guiu.rocafort.ferrerI updated the issue branch with the latest 2.0.x branch, and solved some merge conflicts.
I was not able to configure and run (yet) the Functional Javascript tests locally, so pushing to see if it passes the tests in the Gitlab pipelines.
I am planning on working on this in the following days.
Comment #31
godotislateFYI: New hooks
hook_entity_duplicate()andhook_ENTITY_TYPE_duplicate()have been committed to Drupal core and will be available in Drupal 11.2. A universal approach that works for all the cloning modules might be possible using those hooks, when sites are running 11.2+.Comment #32
anybodyGreat news @godotislate!!
@justin2pin what do you think regarding that (#31) and the state of this issue? There still seems no clean way to clone nodes with Layout Builder on it? How should we proceed?
Comment #43
anybody@guiu.rocafort.ferrer are you planning to further work on MR!69 in the meantime? I tried replicating it to 2.2.x and 3.0.x but then saw that it seems to be incomplete compared to #15? So definitely needs work, while
#31 seems to be the correct way to go.
Very much hoping for feedback from @justin2pin :)
Update:
In #3546997: Starting with Drupal ^11.2 with latest Paragraph do not need Paragraphs duplicates there's being worked with the new hooks in Quick Node Clone!
Paragraphs also already implemented the new hooks: #3495373: Support duplicate hook