-
Notifications
You must be signed in to change notification settings - Fork 2
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:
- 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 - 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). - 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();
}
}
}Introduction
- Tips & Tricks
-
General Processes
- Cleaning up Site Prior to Split
- Cleaning up Site After Split (Workflow/Page Types)
- Go through Template Configuration
- Go through Section Configuration
- Go through Widget Configurations
- Checking Conversions
- Converting Page Types
- Converting Forms
- Final Database operations
- Preserving Navigation Redirects
- Upgrade Procedure