Integrate Sitecore Dictionary into SXA Rendering Variants

Sitecore Experience Accelerator can help you the speed up the production of website on so many levels like different work run in parallel, use of reusable renderings. It is impressive how quickly you can build even a simple site using existing OTTB Rendering Variants. The ease of creating those variants is breathtaking. It is easy to connect your component to Sitecore items fields. In multi-language implementations, the integration with Sitecore dictionary is missing IMHO. You can use Text Rendering Field and then use a different value for each language, but this translation scope limits to this Rendering Variant. What if, for the brand consistency, we want to use the Dictionary for translation and leverage SXA ease of creating new variants without any code change.

The solution – new Rendering Variant Field – Dictionary Text.

It behaves exactly like Text Rendering Field except the string value comes from Sitecore Dictionary.

How to achieve this ? Few simple steps:

Create a parser

 using Sitecore.Data;
 using Sitecore.XA.Foundation.SitecoreExtensions.Extensions;
 using Sitecore.XA.Foundation.Variants.Abstractions.Pipelines.ParseVariantFields;
  
 namespace Project.Foundation.DictionaryText.pipelines.parseVariantFields
 {
     public class ParseDictionaryText : ParseVariantFieldProcessor
     {
         public override ID SupportedTemplateId => new ID("{CA998620-F034-4EC1-BBCA-66863E4624DE}");
  
         public override void TranslateField(ParseVariantFieldArgs args)
         {
             var variantFieldArgs = args;
             var variantText = new Models.DictionaryText(args.VariantItem);
             variantText.ItemName = args.VariantItem.Name;
             variantText.Text = args.VariantItem[Sitecore.XA.Foundation.RenderingVariants.Templates.VariantText.Fields.Text];
             variantText.DictionaryKey = args.VariantItem[Templates.VariantText.Fields.DictionaryKey];
             variantText.Tag = args.VariantItem.Fields[Sitecore.XA.Foundation.RenderingVariants.Templates.VariantText.Fields.Tag].GetEnumValue();
             variantText.IsLink = args.VariantItem[Sitecore.XA.Foundation.RenderingVariants.Templates.VariantText.Fields.IsLink] == "1";
             variantText.LinkField = args.VariantRootItem[Sitecore.XA.Foundation.Variants.Abstractions.Templates.IVariantDefinition.Fields.LinkField];
             variantText.CssClass = args.VariantItem[Sitecore.XA.Foundation.RenderingVariants.Templates.VariantText.Fields.CssClass];
             variantFieldArgs.TranslatedField = variantText;
         }
     }
 } 

Create Rendering

 public class RenderDictionaryText : RenderRenderingVariantFieldProcessor
     {
         public override Type SupportedType => typeof(Models.DictionaryText);
  
         public override RendererMode RendererMode => RendererMode.Html;
  
         public override void RenderField(RenderVariantFieldArgs args)
         {
             if (!(args.VariantField is Models.DictionaryText variantField))
             {
                 return;
             }
  
             var dictionaryRepository = ServiceLocator.ServiceProvider.GetService<IDictionaryRepository>();
             var control = (Control)new LiteralControl(dictionaryRepository.GetValue(variantField.DictionaryKey));
             if (variantField.IsLink)
             {
                 control = InsertHyperLink(control, args.Item, variantField.LinkAttributes, variantField.LinkField, false, args.HrefOverrideFunc);
             }
  
             if (!string.IsNullOrWhiteSpace(variantField.Tag))
             {
                 var tag = new HtmlGenericControl(variantField.Tag);
                 AddClass(tag, variantField.CssClass);
                 AddWrapperDataAttributes(variantField, args, tag);
                 MoveControl(control, tag);
                 control = tag;
             }
  
             args.ResultControl = control;
             args.Result = RenderControl(args.ResultControl);
         }
     }
 } 

CREATE MODEL and REGISTER with DI

 using Sitecore.XA.Foundation.RenderingVariants.Fields;
 using Sitecore.Data.Items;
  
 namespace Project.Foundation.DictionaryText.Models
 {
     public class DictionaryText : VariantText
     {
         public DictionaryText(Item variantItem) : base(variantItem)
         {
         }
  
         public static new string DisplayName => "Dictionary Text";
  
         public string DictionaryKey { get; set; }
     }
 } 

CREATE Rendering view

 @using Sitecore.XA.Foundation.MarkupDecorator.Extensions
 @using Sitecore.XA.Foundation.RenderingVariants.Extensions
 @using Sitecore.XA.Foundation.SitecoreExtensions.Extensions
  
 @model Project.Foundation.DictionaryText.Models.DictionaryTextModel
  
 @if (Model.DataSourceItem != null || Html.Sxa().IsEdit)
 {
     <div @Html.Sxa().Component(Model.Rendering.RenderingCssClass ?? "promo", Model.Attributes)>
         <div class="component-content">
             @if (Model.DataSourceItem == null)
             {
                 @Model.MessageIsEmpty
             }
             else
             {
                 foreach (var variantField in Model.VariantFields)
                 {
                     @Html.RenderingVariants().RenderVariant(variantField, Model.Item, Model.RenderingWebEditingParams, Model)
                 }
             }
         </div>
     </div>
 } 

register PIPELINES

Add A Rule to make a new rendering variant field AVAILABLE for new rendering variants