Try our conversational search powered by Generative AI!

Is there a way of knowing if a block is in the context of a visitorgroup?


Im looking to log statistics of what visitorgroup is used for a block in a contentarea.

From the controller OR view, is this information available somewhere in the Request/DataRoute/ViewBag/TempData?

If not, why not?

Feb 01, 2024 8:46

Hi Luc, not sure if this helps - there's a CMS gadget built by David Knipe that shows editors the visitor group usages for a page or block.

It's for v11 but have a look at the code to find a content item's visitor groups.

Hopefully will give you some direction for what you need.

Edited, Feb 06, 2024 1:31

Thanks Ronil, Not quite what i was looking for, David-tec code is analyzing ContentAreas which visitor group is used where. Thanks anyway.

Anyone else, can i intercept some visitor group validator maybe?

Feb 06, 2024 8:55

Hi Luc.

It looks like you should be able to get a list of the visitor groups applied to a block from the "Context.Items" collection in the block's view like this:

var visitorGroups = Context.Items["EPi:VisitorGroupRoleMatch:"] as Dictionary<string, bool>;

For a given block, that gives the name of the applied visitor group and whether it's a match.

Feb 06, 2024 9:41
valdis - Feb 06, 2024 9:53
Paul, who adds this to the context?

Yes, found it.

Luc, be aware that there is a diff in key names:

  • "EPi:VisitorGroupRoleMatch:" - for anonymous
  • "EPi:VisitorGroupRoleMatch:" + {principal.Identity.Name} - for authenticated users
Feb 06, 2024 9:59
Paul Gruffydd - Feb 06, 2024 10:22
Ah, that would explain the trailing ":".

Is it showing "EveryOne sees" too?

Feb 06, 2024 10:08

Just looking at the value in Context.Items again, I think that value would be set per request rather than per block so it would contain a list of all of the visitor groups used on the current page and whether the current user is a member of that group. If that's all you need then great, but if you need to know, at a block level, which visitor groups are applied to that block, I think you'll need to add that data yourself earlier in the process. If you're rendering content areas using Html Helpers (e.g. Html.PropertyFor()) you could create your own ContentAreaRenderer which overrides the RenderContentAreaItem method to get the visitor group restrictions applied to the current item and pass them through to the view, something like this:

public class CustomContentAreaRenderer(IVisitorGroupRepository _vgRepo) : ContentAreaRenderer
    protected override void RenderContentAreaItem(IHtmlHelper htmlHelper, ContentAreaItem contentAreaItem, string templateTag, string htmlTag, string cssClass)
        //Get the allowed roles for the block and return any that are valid GUIDs
        var visitorGroupGuids = contentAreaItem.AllowedRoles?.Select(x => Guid.TryParse(x, out var vgid) ? vgid : Guid.Empty).Where(x => x != Guid.Empty);

        //Get the visitor group corresponding to each GUID from the IVisitorGroupRepository instance
        var visitorGroups = visitorGroupGuids.Select(_vgRepo.Load);

        //Add the list of visitor groups to the view bag to pass into the view
        htmlHelper.ViewBag.VisitorGroups = visitorGroups;

        //Render as usual
        base.RenderContentAreaItem(htmlHelper, contentAreaItem, templateTag, htmlTag, cssClass);
Feb 06, 2024 14:46
valdis - Feb 06, 2024 22:47
Paul, what I was thinking - the issue with this code is that it will store all VG attached to the content group (and not the ones that matched the request and were applied while rendering the content area item).

But I might be half-way through getting it working..

(just interesting exercise)

Actually yes, this might work :)

Might be cool addition to AdvancedContentArea addon..

Will see, worth squeezing in.

Feb 06, 2024 16:05

actually runing this piece of code in the view... if it is used, the pair.value is true. So far so good. 

BUT! when you are anonymous, and a block is shown with a visitor group, i see no "EPi:VisitorGroupRoleMatch:"  in the list, somethings weird.

    // Define a local function within Razor syntax
    Func<System.Collections.IDictionary, string, string> FindAndJoin = (table, keyPrefix) =>
        foreach (DictionaryEntry entry in table)
            if (entry.Key.ToString().StartsWith(keyPrefix) && entry.Value is Dictionary<string, bool> dictionary)
                System.Text.StringBuilder sb = new System.Text.StringBuilder();
                foreach (var pair in dictionary)
                    if (pair.Value)
                    sb.AppendLine($"Used visitorgroup: {pair.Key} : {pair.Value}");
                return sb.ToString();
        return "No matching key found or value is not a Dictionary.";


@FindAndJoin(Request.RequestContext.HttpContext.Items, "EPi:VisitorGroupRoleMatch:")
Edited, Feb 06, 2024 16:09
valdis - Feb 06, 2024 17:37
Let me play around a bit with this..
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.