Skip to content

Instantly share code, notes, and snippets.

@AThraen
Created September 3, 2018 15:33
Property Inheritance in Episerver CMS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace AllanTech.Web.PropertyInheritance
{
public class InheritAttribute : Attribute
{
/// <summary>
/// Name of Boolean property that indicates if this property should be inherited
/// </summary>
public string SwitchPropertyName { get; set; }
/// <summary>
/// Inherit this value if it's null
/// </summary>
public bool InheritIfNull { get; set; }
/// <summary>
/// Inherit this value if it's null or empty
/// </summary>
public bool InheritIfNullOrEmpty { get; set; }
/// <summary>
/// Name of property on parent content to inherit from. Default is same name.
/// </summary>
public string ParentPropertyToInheritFrom { get; set; }
/// <summary>
/// Keep searching ancestors until Root
/// </summary>
public bool SearchAllAncestors { get; set; }
}
}
using EPiServer.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using AllanTech.Web.Helpers;
using EPiServer.ServiceLocation;
using EPiServer;
using EPiServer.Data.Entity;
using System.Reflection;
namespace AllanTech.Web.PropertyInheritance
{
public static class PropertyInheritor
{
public static T PopulateInheritedProperties<T>(this T Content) where T : PageData
{
var rt = (Content as IReadOnly).CreateWritableClone() as PageData;
var props = Content.GetPropertiesWithAttribute(typeof(InheritAttribute));
bool modified = false;
foreach (var prop in props)
{
var attr = prop.GetCustomAttribute<InheritAttribute>(true);
if (
(!String.IsNullOrEmpty(attr.SwitchPropertyName) && ((bool)Content.GetType().GetProperty(attr.SwitchPropertyName).GetValue(Content))) ||
((attr.InheritIfNull || attr.InheritIfNullOrEmpty) && (prop.GetValue(Content) == null)) ||
(attr.InheritIfNullOrEmpty && ((prop.PropertyType == typeof(ContentArea)) && (prop.GetValue(Content) as ContentArea).Count == 0))
)
{
//Resolve Inherited Properties
var repo = ServiceLocator.Current.GetInstance<IContentRepository>();
foreach(var a in repo.GetAncestors(Content.ContentLink).Take((attr.SearchAllAncestors)?1000:1))
{
var parentprop = (a as IContentData).Property[attr.ParentPropertyToInheritFrom ?? prop.Name];
if (parentprop!=null && !parentprop.IsNull)
{
prop.SetValue(rt, parentprop.Value);
modified = true;
break;
}
}
}
}
if (modified)
{
rt.MakeReadOnly();
return rt as T;
}
return Content;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment