Personalisation + Validation

Vote:
 

I've a 'ContentArea' with a 'LimitContentAreaItems' validator attribute attached, but my issue is that the editors may wish to personalize items in the ContentArea, but the validation attribute doesn't take Personalisation into account when counting the blocks in the contentArea. Is it possible for me to write my own custom validator that could allow, for example, 4 items, but 2 items in each visitor group, so that validator will see that there are only ever 2 items enabled at once? So in the example I want to limit it too 2 items, but allow several personalisations such that the contentArea actually has several more items than just the 2.

#199597
Dec 03, 2018 11:54
Vote:
 
#199598
Dec 03, 2018 12:04
Vote:
 

thanks @David, unfortunately the code at the website doesn't work for me (compiles but doesn't count correctly). I'm not sure 'ContentArea.ContentGroup' is the correct property, especially as I had presumed if the personalisation is listed with two different groups then there'd be two different ContentGroups listed, which isn't the case, but instead "AllowedRoles" array always (in my tests) has the correct number of items in it.

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var contentArea = value as ContentArea;
            
            if (contentArea == null) return null;
            if (contentArea.Items == null) return null;

            int ungroupedItems = 0;
            Dictionary<string, int> groupedItems = new Dictionary<string, int>();  

            foreach (var item in contentArea.Items)
            {
                if (item.AllowedRoles == null || !item.AllowedRoles.Any())
                {
                    ungroupedItems++;
                    continue;
                }

                foreach (var role in item.AllowedRoles)
                {
                    if (string.IsNullOrEmpty(role))
                    {
                        ungroupedItems++; // not sure why it would be null at this point, but handle it anyway
                    }
                    else
                    {
                        // add or insert into the dictionary
                        if (groupedItems.ContainsKey(role)) groupedItems[role] = groupedItems[role] + 1;
                        else groupedItems.Add(role, 1);
                    }
                }
            }

            foreach (var item in groupedItems)
            {
                // loop through dictionary, adding ungrouped (always visible) to conditional groups
                if (item.Value + ungroupedItems > _maxAllowed)
                {
                    return new ValidationResult(
                        $"The property \"{validationContext.DisplayName}\" is limited to {_maxAllowed} items");
                }
            }

            int i;

            return null;
        }

#199661
Edited, Dec 05, 2018 11:07
Vote:
 

Hi Noel,

I'm not entirely sure of what you're trying to count in the contentarea. From looking at the code above, it looks like you're validating against the number of times a given visitor group is used to personalise content + the number of items which don't have personalisation applied. Would you be able to post a screenshot (or even a few) of your content area in the CMS and what you would expect the count to be. For example, for the screenshot below, I'd expect the count that I'm validating to be 4 as no more than 4 items will be shown at any given time so, if I've set the max number allowed to 3, I'd expect it to fail the validation:

#199682
Edited, Dec 05, 2018 11:59
Vote:
 

Hi @Paul, sorry for the delay, I been out of the office last couple of days.

According to your screenshot, because you used the "everyone" group, using AllowedRoles/Visitor groups (my code), the validation fails (but should pass if you remove the "everyone" group). My Code would find 3 ungrouped + 3 groups of 1 (essentially ingoring contentgroups),and therefore fail. But using the "ContentGroup", validation with your code would fail because the 2nd personalization group has 3 items in it, but only 2 items will be shown at once for that personalization group (new members + everyone OR members + everyone). I presume your code would find 1 + 2 OR 3 + 2, because it only looks at groups and not roles.

The first change I made to your code was to remove the LINQ statement, it wasn't working and I couldn't debug why, but otherwise I'm not sure I should be relying on "AllowedRoles" exclusively, but "ContentGroup" only relates to the personalization group, it doens't take into account the visitor group etc. Bearing in mind, I dont think a perfect solution is possible because visitor groups can overlap, so one visitor could match 2 groups and pull in extra items anyway.

From your screenshot, this is the first time I've seen more than a single personalisation group in use,  I didn't test with more than 1 personalization group when I wrote my code and I'm not sure the purpose of 2 seperate personalization groups that are using different visitor groups anyway (but then I am still fairly new to episerver)

#199789
Edited, Dec 11, 2018 15:25
Vote:
 

we're relatively new to personalisation in EPiServer too and we've just run a campaign landing page which needed multiple personalisation groups in order to structure the layout of the page depending on which visitor group was being catered for:

lots of ways to implement this I guess and the above is what we came up with :)

#199889
Dec 17, 2018 14:17
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.