Copying Sitecore Items across Languages

When using multiple languages/cultures in the Sitecore CMS the content of an item isn’t usually copied over from an existing language to a new language version.

While working on a multi lingual website after content was added to the primary language (en-US) I had to write a script to copy all fields from the primary language into other languages (Example en-GB).

Here is some code that I used for Sitecore 6.2.

The following method copies an item from the Source Language to a Target Language provided that the source item has at least one version. Note that if the Target Item lacks a version one is created and only the custom fields (ones not starting with a __) are copied over.

void Copy(Sitecore.Data.Items.Item item, Sitecore.Globalization.Language sourceLanguage,

             Sitecore.Globalization.Language targetLanguage)

        {

            //get a reference to the master DB

            Sitecore.Data.Database masterDB = Sitecore.Configuration.Factory.GetDatabase("master");

            Sitecore.Data.Items.Item targetItem = masterDB.Items[item.ID, targetLanguage];

            Sitecore.Data.Items.Item sourceItem = masterDB.Items[item.ID, sourceLanguage];

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

                return;

            //Disable the security context

            using (new Sitecore.SecurityModel.SecurityDisabler)

            {

                try

                {

                    if (targetItem.Versions.Count == 0)

                    {

                  //add a version if none exist

                        targetItem = targetItem.Versions.AddVersion;

                    }

                    //edit item in target language

                    targetItem.Editing.BeginEdit;

                    sourceItem.Fields.ReadAll;

                    //copy over all fields from source to target language

                    //we omit internal fields which start with __

                    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 following method copies an item from a Source Language to a Target language. In this case two items can be different but are expected to have the same Fields.

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

                }

            }

        }

You can call the above methods after querying Sitecore’s Master DB for items you would like to clone.

protected void Import(object sender, EventArgs e)

        {

            try

            {

                Sitecore.Data.Database masterDB = Sitecore.Configuration.Factory.GetDatabase("master");

                Sitecore.Data.Items.Item[] items = Sitecore.Context.Database.SelectItems

                 ("/sitecore/content/Home/MySectionToCopy//*");

                //get source and target language for the copy

                Sitecore.Globalization.Language sourceLanguage = Sitecore.Data.Managers.LanguageManager.GetLanguage("en-US", masterDB);

                Sitecore.Globalization.Language targetLanguage = Sitecore.Data.Managers.LanguageManager.GetLanguage("en-GB", masterDB);

                if (sourceLanguage == null || targetLanguage == null)

                    return;

                foreach (Item item in items)

                {

                  //copy item from source to target language

                    Copy(item, sourceLanguage, targetLanguage);

                }

            }

            catch (Exception ex)

            {

                Response.Write(ex.Message);

            }

        }

Note: You also have the option to plug into Sitecore’s event pipeline and automatically copy a source language into the target language when a version is added.

More on Event Handling in Sitecore here:

This article is part of the GWB Archives. Original Author: Asif Maniar

New on Geeks with Blogs