Creating pages with editable areas in ASP.NET Core

After you enable the page builder feature in your Core application, create pages with editable areas where content editors can add content through widgets. Content editors can arrange widgets using predefined layouts to achieve their desired result without having to resort to coding. You can adjust the visual arrangement of widgets on a page through the following components:

  • Editable areas – defined directly in the views of your site's pages. They are the top-level layout component and may contain any number of sections.
  • Sections – customizable components that specify the visual layout of widget zones. In the Pages application, content editors can choose which sections to add within editable areas, and thus adjust the structure of the page. A section may contain multiple widget zones. See Developing page builder sections.
  • Widget zones – components that allow content editors to insert widgets. Widget zones are defined in views of sections.

Page builder component hierarchy

On this page

Creating a page

  1. Open the Xperience administration interface.
  2. In the Page types application, set up a page type with the Page builder and URL features enabled.
  3. If your site uses custom routing based on URL patterns, specify a URL pattern for the page type.
    • The URL pattern of the page must match the route template under which the pages are served by the Core application. For example, if you use the /Home URL pattern, the page builder must be located on your Core site's example.com/Home page.
  4. In the Pages application, create a page of the appropriate page type in the content tree.

Initializing the page builder

Page builder initialization is performed during the initialization of the page's data context.

  • On sites that use content-tree based routing, the page data context initialization is handled for you automatically by the system.
  • On sites where routing is handled by custom routes based on page type URL patterns, you need to initialize the page data context manually.

    Manual initialization of the page data context
            private readonly IPageRetriever pagesRetriever;
            private readonly IPageDataContextInitializer pageDataContextInitializer;
     
            // Gets instances of required services using dependency injection
            public PageBuilderInitializationExample(IPageRetriever pagesRetriever,
                                                    IPageDataContextInitializer pageDataContextInitializer)
            {
                this.pagesRetriever = pagesRetriever;
                this.pageDataContextInitializer = pageDataContextInitializer;
            }
     
            public ActionResult Home()
            {
                // Retrieves a page from the Xperience database with the '/Home' node alias path
                TreeNode page = pagesRetriever.Retrieve<TreeNode>(query => query
                                    .Path("/Home", PathTypeEnum.Single))
                                    .FirstOrDefault();
     
                // Responds with the HTTP 404 error when the page is not found
                if (page == null)
                {
                    return NotFound();
                }
     
                // Initializes the page data context (and the page builder) using the retrieved page
                pageDataContextInitializer.Initialize(page);
     
                return View();
            }
    

    Pages protected by authorization

    If the GET action of the controller that handles a page's URL (route) is protected by an Authorize attribute, you may need to take additional steps to ensure that users can work with the page builder. With most configurations, any user can edit the page via the page builder, given the user has permissions necessary to modify the page in the content tree.

    However, if the Authorize attribute has the Users or Roles parameter specified , only users fulfilling the authorization criteria have access to this page in the Pages application. In these cases, you need to include your content editors to allow them access.

Adding editable areas to views

Identify the locations on your website where you want editors to place widgets. Then define these locations by adding editable areas to the code of the corresponding views. The identifier of each editable area must be a string without white spaces that is unique within the context of the given page:

Required namespaces
@using Kentico.PageBuilder.Web.Mvc
@using Kentico.Web.Mvc
<div>
    @await Html.Kentico().EditableAreaAsync("area1")
</div>
You can optionally specify a default section for each area.

  1. Create an EditableAreaOptions object.
  2. Set the object's DefaultSectionIdentifier property to match the identifier of the section which you want to use as default.
  3. Assign the object as a parameter of the EditableAreaAsync extension method (or its Tag Helper alternative) used to render the given area.

The default section is automatically added into new areas and in cases where an editor removes the last section from an area.

<div>
    @{
        var optionsDefaultSection = new EditableAreaOptions
        {
            DefaultSectionIdentifier = "LearningKit.Sections.Col5050"
        };
    }
    @await Html.Kentico().EditableAreaAsync("areaWithSection", optionsDefaultSection)
</div>
If you do not specify the default section for an area, it uses the default section configured for the entire page builder (either the system's Default section with a single widget zone, or a custom section assigned when enabling the page builder feature).

Loading page builder scripts and styles

All pages with editable areas must contain scripts and CSS styles required by the page builder and its components. To add these resources to pages, call the following extension methods (or their Tag Helper alternatives) in your views:

  • Html.Kentico().PageBuilderScripts – renders required script tags and script file links. Call before the closing </body> tag of the page code.
  • Html.Kentico().PageBuilderStyles – renders links for the required stylesheet files. Call within the <head> tag of the page code.

    @using Kentico.Web.Mvc
    @using Kentico.PageBuilder.Web.Mvc
    
    <html>
    <head>
    	...
        @Html.Kentico().PageBuilderStyles()
    </head>
    <body>
        ...
        @Html.Kentico().PageBuilderScripts()
    </body>
    </html>

    For views with an assigned layout, we recommend using Razor sections. Sections allow you to call the methods in the appropriate part of the overall page code, but only for pages that contain editable areas.

The helpers include scripts and styles used in the system's editing interface, as well as those of individual page builder components (widgets, sections, inline property editors, page templates). See the linked documentation to learn how to correctly add custom scripts and styles for your own components.

Replacing default jQuery libraries

By default, the system links two jQuery bundles required for the correct functioning of the form and page builder and their default components: jquery-3.5.1.js and jquery.unobtrusive-ajax.js (not to be confused with the jquery.validate.unobtrusive.js library).

If you wish to use a different jQuery version, specify the path to your custom jQuery bundles via the FormBuilderBundlesOptions options object. See Replacing the default jQuery libraries used by the form builder for more information.

After adding editable areas to views and ensuring that the pages contain the required scripts and styles, you can see the page builder with the editable areas in the Pages application.

Limiting components allowed in an editable area

You can define widget restrictions for certain areas. To limit which components (widgets or sections) can be added to a specific area:

  1. Create an EditableAreaOptions object.
  2. Assign a list of strings to the object's AllowedWidgets and/or AllowedSections property.
  3. Assign the EditableAreaOptions object as a parameter of the EditableAreaAsync extension method used to render the given area.

The allowed components parameters work as a whitelist – you list the components that you want to allow in the editable area, and all others are automatically excluded. When allowed components are not specified, all registered components can be added to the area. You can also set the properties to the following special values:

  • AllowedComponents.ALL – all components are allowed within the editable area.
  • AllowedComponents.NONE – no components are allowed within the editable area (equivalent to an empty list of identifiers).
    • Use the NONE option when limiting sections – this "locks in" the default section for the given area and completely prevents editors from adding further sections of any type.

Tip: Prepare the identifiers of allowed components as a string array, and then assign the array to the appropriate property of the EditableAreaOptions object.

Example
<div>
    @{
        var optionsLimited = new EditableAreaOptions
        {
            AllowedWidgets = new[] { "LearningKit.Widgets.NumberWidget",
                                     "LearningKit.Widgets.SomeOtherWidget" },
            AllowedSections = AllowedComponents.ALL
        };
    }
    @await Html.Kentico().EditableAreaAsync("limitedArea", optionsLimited)
</div>
When adding a new widget or section to the limited editable areas in the Pages application, editors can now only choose from the set of allowed components. When dragging widgets or sections between areas, the interface visually distinguishes between areas where you can and cannot drop the components.

Note: The component limiting feature is intended as a way to set guidelines for content editors, not as a security measure. When you limit an area, existing instances of widgets and sections placed in the area are not validated or removed.

Accessing the page builder configuration of the current page

You can access the page builder configuration of the current page via the IPageBuilderDataContextRetriever service and its Retrieve method. The method returns an IPageBuilderDataContext object that contains the configuration in its Configuration property.

The configuration is stored in the following structure:

  • Page – The root of the configuration
    • EditableAreas – contains a list of all editable areas on the page
      • Sections – contains section properties and all widget zones held within
        • Zones – contains the identifier of the zone and a list of all widgets held within
  • PageTemplate – contains page template metadata (the template's identifier and properties)

You can use the configuration if you wish to develop components that react to the presence of other components on the page.

Checking for component rendering context

To check whether the currently processed component is being rendered on the live site or in the Pages application in the Xperience administration, use the EditMode property of the IPageBuilderDataContext object. Use this property to make sure code specific to the live site does not execute when editing the component in the administration application and vice versa.

// Stores an instance of the IPageBuilderDataContextRetriever service (e.g., obtained using dependency injection)
private readonly IPageBuilderDataContextRetriever pageBuilderDataContext;

if (pageBuilderDataContext.Retrieve().EditMode)
{
	// Targeted custom logic
}

Was this page helpful?