This blog post will discuss MultiSite validation for either ContentArea or LinkItemCollection, which are both capable of storing multiple items. Although we can use the custom MaxItem attribute to validate the ContentArea or LinkItemCollection, the problem arises when the same property is used for multiple sites with different validation limits.
In a recent project, we were tasked with migrating multiple websites into a single platform using Optimizely. These sites shared common ContentTypes wherever applicable, though their behavior varied slightly depending on the site.
One of the main challenges involved a ContentType used as the StartPage with the same properties across different sites. While the structure remained the same, the validation rules for its properties differed based on the specific site requirements. A common issue was enforcing a maximum item validation limit on a property like a ContentArea, where each site had a different limit—for example, Site A allowed a maximum of 3 items, while Sites B and C allowed 4 and 5 items, respectively.
To solve this multisite validation scenario, we implemented a custom validation attribute that dynamically validated the maximum item limit based on the current site context.
Below are the steps we followed to achieve this.
- Make a MaxItemsBySitesAttribute custom validation attribute class and add an AttributeUsage attribute with AllowMultiple = true.
- Then inherit from ValidationAttribute as a base class. This class is used to provide server-side validation rules on content properties for Block, Page, or Media content types.
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] public class MaxItemsBySitesAttribute : ValidationAttribute { private readonly string[] _siteName; private int _max; public MaxItemsBySitesAttribute(int max, params string[] siteName) { _max = max; _siteName = siteName; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var siteSpecificLimit = GetSiteSpecificMaxLimitByFieldName(validationContext.MemberName, validationContext?.ObjectType?.BaseType); string errorMsg = $"{validationContext.DisplayName}, exceeds the maximum limit of {siteSpecificLimit} items for site {SiteDefinition.Current.Name}"; if (value is ContentArea contentArea) { if (contentArea.Count > siteSpecificLimit) { return new ValidationResult(errorMsg); } } else if (value is LinkItemCollection linkItems) { if (linkItems.Count > siteSpecificLimit) { return new ValidationResult(errorMsg); } } return ValidationResult.Success; } private int GetSiteSpecificMaxLimitByFieldName(string fieldName, Type type) { var propertyInfo = type.GetProperty(fieldName); if (propertyInfo != null) { var attributes = propertyInfo.GetCustomAttributes<MaxItemsBySitesAttribute>()?.ToList(); var siteMaxLimit = attributes.FirstOrDefault(x => x._siteName != null && x._siteName.Any(site => site == SiteDefinition.Current.Name)); return siteMaxLimit == null ? 0 : siteMaxLimit._max; } return 0; } }
-
- The function GetSiteSpecificMaxLimitByFieldName() in the above code played an important role in this class to retrieve decorated attribute(s) [MaxItemsBySites(2, “AlloyBlog”)] and [MaxItemsBySites(3, “AlloyDemo”, “AlloyEvents”)] with specified item limit counts and site names.
- Then, decorate the [MaxItemsBySites] custom attribute(s) on the ContentArea or LinkItemCollection property by adding the maximum item limit and site(s) name as given below.
public class StartPage : SitePageData { [Display( GroupName = SystemTabNames.Content, Order = 320)] [CultureSpecific] [MaxItemsBySites(2, "AlloyBlog")] [MaxItemsBySites(3, "AlloyDemo", "AlloyEvents")] public virtual ContentArea MainContentArea { get; set; } }
- The attribute will receive a trigger and verify the maximum item limit and site name against the site that is currently running and display an error message below if validation matches.
By implementing site-specific maximum item validation in your Optimizely CMS multisite, content authors can ensure content consistency, enhance user experience, and maintain precise control over content areas and link collections across diverse properties in different sites.
In case you want other validation by site-specific, you can use the same approach by changing the code accordingly.
Source: Read MoreÂ