detect if an editable area contains any widgets

Turner Drive asked on October 23, 2020 07:19

I'm building a site in Kentico 12 MVC and working on setting up content personalization. The normal way to do this is to add an editable area in the view:

@Html.Kentico().EditableArea("area1")

Then, in the CMS, the Page tab will show an empty area where the user can add a widget with personalized content.

The problem is that the content I want to personalize is located in my site's login box, which is a common element on every page, so I'd need to manually add a widget into the editable area on every page individually. But my site has over 300 pages, so that's totally impractical.

Is there a way from within my view model that I could check if the editable area has any widgets, and if it doesn't, output default content instead? I'm trying to see if there's an API method or something that would let me count the number of widgets inside an editable area, but I can't find anything in the documentation.

Recent Answers


Michal Samuhel answered on October 23, 2020 17:23 (last edited on October 23, 2020 17:25)

You could resolve service Service.Resolve<IPageBuilderDataContextRetriever>() and than parse serialized property PageBuilderConfiguration Configuration to get all widgets within a page.

Though this is just a shot on API which I discovered yesterday as public members and had not really used it anywhere.

0 votesVote for this answer Mark as a Correct answer

Sean Wright answered on October 31, 2020 18:04

Just to note, IPageBuilderDataContextRetriever only exists in Xperience 13.0+, not in v12.

If you are working in v12...

You can retrieve the DocumentPageBuilderWidgets column from the CMS_Document page for the current page and parse the JSON inside, but there are no APIs to help you here.

If you need to be able to control the content in the Page Builder components (Editable Areas, Sections, Widgets, ect...) for many pages at once, you could try my Shared Widget Pages pattern.

There's also a way to reuse the data context. This would allow you to take the Page Builder components from one Page and render them on another one (assuming you have Editable Areas in both pages with the same name). This allows for more of a mashup approach.

0 votesVote for this answer Mark as a Correct answer

Elmar Höfinghoff answered on March 3, 2021 12:17

You can do something like this. My solution in Kentico 12:

using CMS.DocumentEngine;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;

public static class EditableAreaHelper
{
    public static bool HasWidgets(TreeNode page, string areaName)
    {
        string jsonAreaContent = page.GetStringValue("DocumentPageBuilderWidgets", null);
        if (jsonAreaContent == null) {
            return false;
        }

        RootObject root = JsonConvert.DeserializeObject<RootObject>(jsonAreaContent);

        return root.EditableAreas
            .Any(ea => ea.Identifier.Equals(areaName) && ea.Sections
                .Any(s => s.Zones
                    .Any(z => z.Widgets
                        .Any())));
    }


    #region EditableArea Json Object Mapping --------------------------------------------------

    public class RootObject
    {
        public List<EditableArea> EditableAreas { get; set; }
    }
    public class EditableArea
    {
        public string Identifier { get; set; }
        public List<Section> Sections { get; set; }
    }
    public class Section
    {
        public List<Zone> Zones { get; set; }
    }
    public class Zone
    {
        public List<Widget> Widgets { get; set; }
    }
    public class Widget
    {
        public string Type { get; set; }
    }

    #endregion
}
0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.