Problem/Motivation
When cloning a page variant, the cloned one share the same UUID of the original one.
Worse, also the internal panes share the same UUID of the panes of the original variant. For panes, sometimes, it is right to keep the UUID. For example if the pane is a "reusable custom content pane" we would like to keep the original UUID because it's reusable and we want to load the same content. But, for example with simple custom content we need a new UUID because it's a totally independent new content and it has nothing to do with the original one.
This bug makes variants with the same UUID to be skipped when refreshing strings during the translation process.
In i18n_panels this is done by the following lines of i18n_panels.module (function: i18n_panels_i18n_string_list):
// Avoid duplicated runs _18n_panels_fetch_all_panel_displays() probably
// returns the same display twice, one for the db based and one for the
// exported one.
if (isset($strings['panels']['display_configuration'][$display->uuid])) {
continue;
}
The previous code is correct assuming that the UUID is unique. If you clone a variant it's not!
I found out this bug working with i18n_panels, but it's not only related to i18n_panels. It's a more general problem and it must be solved. So, I will mark it as major.
Steps to reproduce the issue
- Enable panels, page_manager, i18n_panels.
- Create a page.
- Create a variant.
- Clone the variant.
Proposed resolution
An approach could be solve the issue when saving the display (panels_save_display).
We can think a way to set the did
of the panel to "cloned"
when it's cloned so we can define a complete different procedure for this case.
Workaround
As a temporary workaround for any issue related to this and translation of custom content proceed as follows:
- Add custom content
- Choose PHP as text format
- Implement the translation with a switch case on the global
$language
variable.
Attached is an export of a simple page that exposed the problem.
To create the exported panel I followed the steps defined above.
What do you think about that?
Please, any suggestion or thought about this issue is well accepted.
Comment | File | Size | Author |
---|---|---|---|
#24 | the_uuids_of_cloned-2253919-24.patch | 2.42 KB | sylus |
#4 | panels-re-generated-uuids-on-clone.patch | 1.96 KB | das-peter |
Comments
Comment #1
goldenboy CreditAttribution: goldenboy commentedComment #2
jweowu CreditAttribution: jweowu commentedYes, this was the notable unresolved issue in #1277908: Introduce UUIDs onto panes & displays for better exportability & features compatibility, and I would love to see some progress made.
das-peter solved some of the issues at the time, and sdboyer's comments (quoted below) were the closest thing we had to a plan for moving forward on the remaining aspects; but we didn't get any further in confirming a solution and working out the exact implementation details.
I've not re-examined the issue (or your suggestion) at this point, but I wanted to cross-reference the issues (I've added this one as a related issue for the original, to try to increase its visibility).
Comment #3
geek-merlinHere is some quickly knitted code that fixes duplicate UUIDs by selecting duplicate ones, unsetting and re-saving them.
It might be the base for a "fix uuids" button. Be sure to "refresh user-defined strings" afterwards.
Comment #4
das-peter CreditAttribution: das-peter commentedHere's a patch that re-generates the uuids when cloning.
I'll open a related issue for page manager.
The patch adds the method
panels_display::clone_display()
, which takes care of re-generating all the uuids.Maybe we even could handle this in the magic method
__clone()
- but I'm not sure if there are cases in whichclone
is used just to decouple one from another instance for other purposes.Comment #5
sylus CreditAttribution: sylus commentedYeah this issue has tripped me up as well. Particularly when you are doing translations for a cloned display that is different. As the string context will be the same so the translation will effect all cloned panels.
Comment #6
chris.guitarte CreditAttribution: chris.guitarte commentedI noticed that the patch does not fix the use-case where we have modified a system page manager page (such as user_view).
When I try to clone the variant under /admin/structure/pages/nojs/operation/user_view/handlers/user_view__custom_user_profile_standard/actions/clone
It simply renames the variant presumably because the UUIDs have not been re-generated.
Comment #7
das-peter CreditAttribution: das-peter commented@usc.guitarte Since page manager is part for ctools it's not part of this patch. Please see the related child issue: #2449245: Cloning page manager handlers leads to duplicated uuids.
Comment #8
ndf CreditAttribution: ndf commentedThink importing needs same behaviour.
So exporting and importing a variant should behave equally as cloning a variant.
Unless you explicitly import with an option like 'overwrite existing variant if it exists'. The UUID can act as identifier for this.
Patch for cloning works well though.
To me this bug can also be a critical one, because translations just don't work. Try to translate a 'manually set Title' for instance one cloned panel-variants/panels.
Comment #9
das-peter CreditAttribution: das-peter commentedCould we do this in a next step?
I think this one was open quite long now and if it's working I'd like to get it in asap.
Comment #10
geek-merlin+1 for #9, rtbc as of #8.
@ndf: feel free to open a followup.
Comment #11
ndf CreditAttribution: ndf commentedFollow-up ticket for importing/exporting: https://www.drupal.org/node/2530158Follow-up ticket merged with Ability to set variant machine name in Panels UI for Cloning and Importing variants
Comment #12
das-peter CreditAttribution: das-peter commented@ndf Thanks, will follow the other issue too.
Comment #13
DamienMcKennaComment #14
Anybody+1 for applying this patch on the next release. The problem is really bad and still exists. Thank you all for your work on it!
Thank you for the script in #3 also.
Confirming the script in #3 and the patch to work. Perhaps the script above should be cleaned and added as hook_update script? Or better not?
Comment #15
DamienMcKennaSo this bug was causing #2577031: Duplicated UUIDs after panelizer page override for specific node from node type template and #2748373: Cloned default displays have duplicate UUIDs, and bugs in other Panels-related modules.
Comment #16
DamienMcKennaThe problem was also being triggered by panels_save_display() when the display is cloned, which happens in Panelizer quite a bit.
Comment #17
DamienMcKennaThis patch also fixes the tests in the two Panelizer issues referenced above.
Comment #18
DamienMcKennaI've moved the panels_save_display() issue to #2750545: New displays saved via panels_save_display() don't reset the UUID to keep it separate.
Comment #19
DamienMcKennaThis wasn't added to 3.6 but it should be added to 3.7.
Comment #20
dsnopekMoving to 3.8 so we can get 3.7 out quicker!
Comment #21
weri CreditAttribution: weri at Previon Plus AG commentedI tested the patch and it generates new uuid's for cloned variants, that's fine. But a problem exists, when we add panel pages to features. Every time I save a variants content, also when nothing is changed, the export gets new uuid's for the panel display. This was not a problem before we used i18n_panels to translate the content of panels, because the translate context contains the uuid (e.g.: pane_configuration:64d4bce6-f0cc-4885-8447-eb2b23631595:body) and the key has to be the same otherwise we loose the translation every time we update a panel.
The problem seems to be in the following part od the code:
When I save or revert an existing panel, always a new uuid is generated, because $update has the value 'new' and is not a numeric value.
Comment #22
DamienMcKenna@weri: That is a completely valid concern. Poop. I won't have time to work on this before Monday, so I'm removing it from the list for consideration.
Comment #23
geek-merlin@weri: yes right!
(thanks for the code snippet).
Background: Contrary to Entity API (which also has DB entries for reverted objects), Ctools does NOT have DB entries for reverted objects, only for overridden ones. So any reverted panel will NOT have a $did.
So in the above code we have to distinguish between 2 casesn when $did is not numeric:
a) panel is cloned
b) panel is overridden
(Maybe this is not possible in this code place, then we have to create or erase the UUID earlier on cloning.)
Comment #24
sylus CreditAttribution: sylus commentedJust attaching a new patch since old one won't apply to new panels release 3.9.
Comment #25
khaldoon_masud CreditAttribution: khaldoon_masud commentedThe fix wasn't included in 7.x-3.9.