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).

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!

|improve this answer|||||
  • 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 '17 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. – Owen Niblock Oct 7 '17 at 11:04
  • I read it wrong. I thought there were 2 options. Sorry. – Richard Seal Oct 7 '17 at 11:07
  • I don't know if it fully answers the question though. Let me reassess and make it more clear later :-) – Owen Niblock Oct 7 '17 at 11:16
  • 1
    @OwenNiblock You can update your answer to both copy the tree and then call Remove-ItemVersion – Michael West Oct 7 '17 at 15:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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