Cloning in Sitecore can be extremely useful. It makes reusing of content items and updating of those items very easy. The default capabilities for item cloning can usually handle most needs. The default behavior does have one thing that can really trip you up. By default clone, child items stay linked to the source cloned item and are not reparented to their new cloned parent. The first thing to understand is there are configuration options for cloning that allow you to change how cloning works. The configuration files have them pretty well documented but if you don't know what you are looking for you may not know they are there.
- <setting name="ItemCloning.Enabled" value="true"/>
- Specifies whether the Item Cloning feature is enabled
- Default value on CM and Standalone servers: true.
- Default value on CD, Processing and Reporting servers: false.
- <setting name="ItemCloning.NonInheritedFields" value=""/>
- Specifies a pipe-separated list of field names or field IDs which should be not be inherited by clones from their source item, in addition to the following fields from the standard template that are never be inherited:
- Updated, Updated by, Revision, Created, Created by, Source, Workflow, Workflow State, Lock
- <setting name="ItemCloning.InheritWorkflowData" value="false"/>
- Specify whether you want the workflow and workflow state fields to be inherited by clones from their source item. Note: When you change the setting value, clones move in or out the workflow, which may affect their behavior, for example, on publishing.
- Default value: false
- <setting name="ItemCloning.ForceUpdate" value="true" patch:source="ClientContent.config"/>
- Specify whether clones should be updated automatically when:
- A new version is added to the original item.
- A new language is added to the original item.
- A new sub-item is added to the original item.
- Note: If true, all the clones of the original item are updated automatically.
- Default value: false
- <setting name="ItemCloning.DeleteClonesWithOriginalItem" value="false"/>
- Specifies whether item clones should be deleted when the original item is deleted.
- If true, when the original item is deleted all its clones are deleted and not just uncloned.
- Default value: false
- <setting name="ItemCloning.ForceUpdate.ChangeTemplate" value="false"/>
- Specify whether clones should be updated automatically when a different template is selected for the original item. Note: If true, all the clones of the original item are updated automatically.
- Default value: false
- <setting name="ItemCloning.RelinkClonedSubtree" value="true" patch:source="ClientContent.config"/>
- Indicates that after cloning an item tree structure, all the internal links inside the cloned structure should be re-linked to point to the items in the cloned sub-tree.
- When the setting value is false, the links in the cloned structure will still link to the items in the original structure.
- Default value: false
We need to go a little deeper on the last one (RelinkClonedSubtree). The reason for this is it only "kind of works". It works when the tree you are cloning is shallow.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public void RelinkClonedSubtree(CopyItemsArgs args) { Assert.ArgumentNotNull((object) args, nameof (args)); Assert.IsNotNull((object) args.Parameters, "parameters"); if (!Settings.RelinkClonedSubtree) return; Item[] copies = args.Copies; Assert.IsNotNull((object) copies, "copies"); foreach (Item obj1 in copies) { if (obj1.SourceUri != (ItemUri) null) { Item obj2 = Database.GetItem(obj1.SourceUri); if (obj2 != null) CorePipeline.Run("replaceItemReferences", (PipelineArgs) new ReplaceItemReferencesArgs() { SourceItem = obj2, CopyItem = obj1, Deep = true, Async = false }); } } |
The "replaceItemReferecnes" only has one processor of "<processor type="Sitecore.Pipelines.ReplaceItemReferences.StartJob, Sitecore.Kernel"/>" and all that processor does it create and trigger an instance of "ReferenceReplacementJob".
Long story short here there are two main issues here. First, there is currently a bug in this functionality as of Sitecore 9.3 where trees with bucketable items don't work when cloning a deep tree. Sitecore support has a bug on this you can reference with number 370689. But if you enable this RelinkClonedSubtree configuration setting the new cloned subtree items will reference the clone parent items instead of the original item it was linked to. For me it feels like this should be the default behavior but at least there is an options to make this work.
Comments