1

I'm trying to make a a function that whenever user saves in the Experience Editor, it copies the rendering of current language version to other 2 language versions. For example, if I'm in Language A (other 2 version are created in current page), I go in Experience Editor, I make some changes and save. Then, all 3 versions should have the same component/module in it's final rendering. Here's my code :

public static void ApplyVersionToOtherLang(Item savedItem)
    {
        if (Sitecore.Context.PageMode.IsExperienceEditor)
        {
            var enLang = Language.Parse("en");
            var enLangItem = savedItem.Database.GetItem(savedItem.ID, enLang);
            if (enLangItem.Versions.Count >  0 && enLangItem.Language.Name != savedItem.Language.Name)
            {
                enLangItem.Editing.BeginEdit();
                var latestVersionFinalLayout = LayoutField.GetFieldValue(savedItem.Fields[FieldIDs.FinalLayoutField]);
                LayoutField.SetFieldValue(enLangItem.Fields[FieldIDs.FinalLayoutField], latestVersionFinalLayout);
                enLangItem.Editing.EndEdit();
            }
            var simplifiedChineseLang = Language.Parse("zh-CN");
            var simplifiedChineseLangItem = savedItem.Database.GetItem(savedItem.ID, simplifiedChineseLang);
            if (simplifiedChineseLangItem.Versions.Count > 0 && simplifiedChineseLangItem.Language.Name != savedItem.Language.Name)
            {
                simplifiedChineseLangItem.Editing.BeginEdit();
                var latestVersionFinalLayout = LayoutField.GetFieldValue(savedItem.Fields[FieldIDs.FinalLayoutField]);
                LayoutField.SetFieldValue(simplifiedChineseLangItem.Fields[FieldIDs.FinalLayoutField], latestVersionFinalLayout);
                simplifiedChineseLangItem.Editing.EndEdit();
            }
            var traditionalChineseLang = Language.Parse("zh-TW");
            var traditionalChineseLangItem = savedItem.Database.GetItem(savedItem.ID, traditionalChineseLang);
            if (traditionalChineseLangItem.Versions.Count > 0 && traditionalChineseLangItem.Language.Name != savedItem.Language.Name)
            {
                traditionalChineseLangItem.Editing.BeginEdit();
                var latestVersionFinalLayout = LayoutField.GetFieldValue(savedItem.Fields[FieldIDs.FinalLayoutField]);
                LayoutField.SetFieldValue(traditionalChineseLangItem.Fields[FieldIDs.FinalLayoutField], latestVersionFinalLayout);
                traditionalChineseLangItem.Editing.EndEdit();
            }
        }
        
    }

The problem is whenever the current item hits EndEdit(), it calls the save function again, and replaces the original version with the version it hits in the IF condition. And this creates unnecessary loop, to the point it freezes the website if I try to change the content and save. Is there any other way to apply final rendering to other versions ?

1

It should be enough to compare if what you want to set to other versions is really different from what is in your current language version. And only in that case start editing the item.

See the code below:

public static void ApplyVersionToOtherLang(Item savedItem)
{
    if (Sitecore.Context.PageMode.IsExperienceEditor)
    {
        var latestVersionFinalLayout = LayoutField.GetFieldValue(savedItem.Fields[FieldIDs.FinalLayoutField]);
        
        ApplyToOtherLanguageIfNeeded(latestVersionFinalLayout, savedItem, "en");
        ApplyToOtherLanguageIfNeeded(latestVersionFinalLayout, savedItem, "zh-CN");
        ApplyToOtherLanguageIfNeeded(latestVersionFinalLayout, savedItem, "zh-TW");
    }
}

private static void ApplyToOtherLanguageIfNeeded(string newLayout, Item layoutSource, string languageName)
{
    if (layoutSource.Language.Name != languageName)
    {
        var targetItem = layoutSource.Database.GetItem(layoutSource.ID, Language.Parse(languageName));

        if (targetItem.Versions.Count > 0
            && newLayout != LayoutField.GetFieldValue(targetItem.Fields[FieldIDs.FinalLayoutField]))
        {
            targetItem.Editing.BeginEdit();
            LayoutField.SetFieldValue(targetItem.Fields[FieldIDs.FinalLayoutField], newLayout);
            targetItem.Editing.EndEdit();
        }
    }
}

This lines checks if there is a need to edit the item:

if (targetItem.Versions.Count > 0
  && newLayout != LayoutField.GetFieldValue(targetItem.Fields[FieldIDs.FinalLayoutField]))
| improve this answer | |
  • thank you it's worked perfectly – Thanh Nguyen Jul 15 at 12:04
1

Assuming your code is triggered in an event, you could use an EventDisabler in your code:

using (new EventDisabler())
{
   ...
}

Or (still in the assumption your code is in an event) you could use the optional parameters of the EndEdit() to do a silent save: use it like EndEdit(false, false) in your case. This will use silent mode (which actually just is the same but with an event disabler) and stop the analytics update.

| improve this answer | |
  • thank you this worked too – Thanh Nguyen Jul 15 at 12:04

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.