4

Is there an efficient way to copy a subtree of items but only keep language versions from the original items that a user chooses? Currently I have a process which duplicates items and then removes the unwanted language version but it is multiple steps. I use Item.CopyTo(Item item, string name) and then loop through the result removing language versions. Then I find what languages to remove and loop through the new items. For each language to remove I get the item in that language and use myItem.Versions.RemoveAll(false).

1 Answer 1

4

I would use PowerShell for this. The simplest way is to use a similar approach to what you're doing now (but in a few less steps):

Copy the item:

Copy-Item -Path $source.ItemPath -Destination $destination.ItemPath -Recursive

Them remove language versions:

Get-ChildItem $destination -Recurse | 
    Remove-ItemLanguage -Language "fr-CA"

However, you could make this a different way by only copying the language versions you want. I'm not sure how you'd do this in PowerShell off the top of my head - but you could do it with some code (you'd need to add some looping to traverse, add items and copy but hopefully this will give you the idea):

void Copy(Sitecore.Data.Items.Item sourceItem, Sitecore.Globalization.Language sourceLanguage,
        Sitecore.Data.Items.Item targetItem, Sitecore.Globalization.Language targetLanguage)
    {
        Sitecore.Data.Database masterDB = Sitecore.Configuration.Factory.GetDatabase("master");

        targetItem = masterDB.Items[targetItem.ID, targetLanguage];
        sourceItem = masterDB.Items[sourceItem.ID, sourceLanguage];

        if (targetItem == null || sourceItem == null || sourceItem.Versions.Count == 0)
            return;

        using (new Sitecore.SecurityModel.SecurityDisabler())
        {
            try
            {
                if (targetItem.Versions.Count == 0)
                {
                    targetItem = targetItem.Versions.AddVersion();
                }
                targetItem.Editing.BeginEdit();
                sourceItem.Fields.ReadAll();
                foreach (Sitecore.Data.Fields.Field field in sourceItem.Fields)
                {
                    if (!field.Shared && !field.Name.StartsWith("__") && field.Name.Trim() != "")
                    {
                        targetItem.Fields[field.Name].SetValue(field.Value, true);
                    }
                }

                targetItem.Editing.EndEdit();
                targetItem.Editing.AcceptChanges();
            }
            catch (Exception ex)
            {
                targetItem.Editing.CancelEdit();
                Response.Write(ex.Message);
            }
        }

    }

(The above method taken from here)

Which of these is most efficient probably depends upon the sort of data you're copying (depth of the tree, number of languages, quantity of items etc).

If it's a process you need to do often as a developer I'd recommend PowerShell. If you need content editors to do it - I'd recommend wrapping it all in a tool (highly recommend Sitecore Sidekick for this).

Hope that helps you find the right solution!

7
  • Can you provide implementation details from the first link please. As is stands this is very close to a link only answer.
    – Richard Seal
    Oct 7, 2017 at 10:54
  • Sure, just out at the mo. I figured it wasn't necessary because it's just a standard part of powershell but I'll flesh it out this evening. Oct 7, 2017 at 11:04
  • I read it wrong. I thought there were 2 options. Sorry.
    – Richard Seal
    Oct 7, 2017 at 11:07
  • I don't know if it fully answers the question though. Let me reassess and make it more clear later :-) Oct 7, 2017 at 11:16
  • 1
    @OwenNiblock You can update your answer to both copy the tree and then call Remove-ItemVersion Oct 7, 2017 at 15:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.