Skip to content

Widget Property Translation Sample Method

Trevor Fayas edited this page Dec 12, 2022 · 1 revision

Often times you need to take an existing widget property (say a Transformation Name) and change it to something else for your KX13 site.

Below is a method that I used to help simplify this processes. It involves the following steps:

  1. Create a Dictionary<string, Dictionary<string, List<KeyValuePair<object, object>>>> Configuration object in the Module class and populate it with Widget Name (to lower), Property Name (to lower) and a list of Key-Value pairs of "Before" to "After" values
  2. Create a Dictionary<string, Dictionary<string, Func<object, object>>> Configuration object in the Module class and populate it with widget name (to lower), property name (to lower), and a function that takes an object (incoming value) and returns an object (converted value).
  3. Add a ProcessWidget.Before method that loops through the widget properties and converts anything found in the dictionary.

Below is my sample code:

[assembly: RegisterModule(typeof(CustomKX12To13ConverterEvents))]
namespace CMSApp.Old_App_Code
{
    public class CustomKX12To13ConverterEvents : Module
    {
        // Configuration Items
        private Dictionary<string, Dictionary<string, List<KeyValuePair<object, object>>>> WidgetConfiguration = new Dictionary<string, Dictionary<string, List<KeyValuePair<object, object>>>>();

        private Dictionary<string, Dictionary<string, Func<object, object>>> WidgetConfigurationToFunction = new Dictionary<string, Dictionary<string, Func<object, object>>>();


        public CustomKX12To13ConverterEvents() : base("CustomKX12To13ConverterEvents")
        {

        }
        protected override void OnInit()
        {
            base.OnInit();
            PortalToMVCEvents.ProcessWidget.Before += ProcessWidget_Before;

            // Switches the Transformation Name for new values for the PragraphWidget
            WidgetConfiguration.Add(
                "ParagraphWidget".ToLower(), new Dictionary<string, List<KeyValuePair<object, object>>>()
                {
                    {
                        "TransformationName".ToLower(), new List<KeyValuePair<object, object>>() {
                            new KeyValuePair<object, object>("Paragraph.Paragraph.Default".ToLower(), "default"),
                            new KeyValuePair<object, object>("Custom.Paragraph.StyledParagraph".ToLower(), "styled")
                        }
                    }
                });

            // Handles the RelationshipWithNodeGuid current document macro / current document guid code to be empty so can default to the current page.
            WidgetConfiguration.Add(
                "RelatedPageCarousel".ToLower(), new Dictionary<string, List<KeyValuePair<object, object>>>()
                {
                    {
                        "RelationshipWithNodeGuid".ToLower(), new List<KeyValuePair<object, object>>() {
                            new KeyValuePair<object, object>("{% NodeGuid %}".ToLower(), ""),
                            new KeyValuePair<object, object>("11111111-1111-1111-1111-111111111111".ToLower(), "")
                        }
                    }
                });

            // Function based configurations
            // Converts the NodeAliasPath to a NodeGuid, and takes only the last part of the Transformation Name for the TilesRepeater widget
            WidgetConfigurationToFunction.Add(
                "TilesRepeater".ToLower(), new Dictionary<string, Func<object, object>>()
                {
                    { "Path".ToLower(),  NodeAliasPathToGuid },
                    { "TransformationName".ToLower(),  TransformationNameRemoveClass }
                }
            );
            // Takes only the last part of the Transformation Name for the ButtonRepeater widget
            WidgetConfigurationToFunction.Add(
                "ButtonRepeater".ToLower(), new Dictionary<string, Func<object, object>>()
                {
                    { "TransformationName".ToLower(),  TransformationNameRemoveClass }
                }
            );
        }
  

        // Widget event that will leverage the dictionaries
        private void ProcessWidget_Before(object sender, PortalToMVCProcessWidgetEventArgs e)
        {
            if (WidgetConfiguration.ContainsKey(e.PortalEngineWidget.Widget.WebPartType.ToLower()))
            {
                var config = WidgetConfiguration[e.PortalEngineWidget.Widget.WebPartType.ToLower()];
                foreach (var key in config.Keys.Where(x => e.PortalEngineWidget.Widget.Properties.Keys.Cast<string>().Contains(x, StringComparer.OrdinalIgnoreCase)))
                {
                    var oldValue = e.PortalEngineWidget.Widget.GetValue(key);
                    var match = config[key].Where(x => (x.Key is string ? x.Key.ToString().ToLower().Equals(oldValue.ToString(), StringComparison.OrdinalIgnoreCase) : x.Key.Equals(oldValue)));
                    if (match.Any())
                    {
                        e.PortalEngineWidget.Widget.SetValue(key, match.First().Value);
                    }
                }
            }
            if (WidgetConfigurationToFunction.ContainsKey(e.PortalEngineWidget.Widget.WebPartType.ToLower()))
            {
                var config = WidgetConfigurationToFunction[e.PortalEngineWidget.Widget.WebPartType.ToLower()];
                foreach (var key in config.Keys.Where(x => e.PortalEngineWidget.Widget.Properties.Keys.Cast<string>().Contains(x, StringComparer.OrdinalIgnoreCase)))
                {
                    var oldValue = e.PortalEngineWidget.Widget.GetValue(key);
                    var newValue = config[key](oldValue);
                    e.PortalEngineWidget.Widget.SetValue(key, newValue);
                }
            }
        }

        // My Property methods for function based transformations
        public static object TransformationNameRemoveClass(object arg)
        {
            string transformationName = ValidationHelper.GetString(arg, string.Empty);
            var split = transformationName.Split(".".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
            if(split.Length >= 3)
            {
                return split.Skip(2).Join(".");
            } else
            {
                return transformationName;
            }
        }

        private static object NodeAliasPathToGuid(object arg)
        {
            string path = ValidationHelper.GetString(arg, string.Empty);
            var match = DocumentHelper.GetDocuments().WhereEquals(nameof(TreeNode.NodeAliasPath), path)
                .Columns(nameof(TreeNode.NodeGUID))
                .TopN(1)
                .Published(false)
                .LatestVersion(true)
                .AllCultures()
                .TypedResult
                .FirstOrDefault();
            if (match != null)
            {
                return match.NodeGUID.ToString();
            }
            return Guid.Empty.ToString();
        }
    }
}

Clone this wiki locally