Page Builder by Kentico Xperience is a very powerful tool for developers and content administrators. Giving this much power to content admins can be a little worrisome when you’re used to more structured content, but giving your content admins the freedom to customize their pages without calling you for redesigns will keep them happy. I’m going to highlight some of our custom generic column section and our carousel and configurator widgets below.
Generic Column Section
Instead of having multiple sections cluttering the section selection menu to handle all the client requirements, we made a generic column section. The section properties has a simple dropdown for the content admin to select the desired number of columns.
In the section’s view, we set the Bootstrap class to the colCount divided by twelve to obtain even Widget Zones. In the case of the admin selecting five columns, Bootstrap rounds down the “2.4” to 2.
The result is dynamic and provides a lot of customization to the content admin without flooding them with too many section options.
We wanted to provide the client with a highly diversifiable carousel widget, so each carousel fits their needs. We’re using SwiperJs for its vast amount of customizations and ease of use. If you look at those Swiper demos, it would’ve been easy for us to go overboard with the widget properties.
Instead, we contained it to what the client specifically wanted and some nice to haves. Using the PathSelector widget property type allowed us to mix structured content and the flexibility of page builder. Before creating the carousel widget, the content admin would need to create the slides by populating a folder with our Slide page type. Then add in the carousel widget and edit the properties to select the folder they just created.
In the CarouselWidgetController class (below), we’re using the selected path to get all the children in that carousel folder and its children (slides).
typeof( CarouselWidgetController ),
IconClass = carouselWidget.IconClassController )]
public class CarouselWidgetController : WidgetController<carouselwidgetproperties>
public ActionResult Index( )
var properties = GetProperties();
CarouselFolder carousel = new CarouselFolder();
List<slide> slides = new List<slide>();
string selectedPagePath = properties.PagePaths?.FirstOrDefault()?.NodeAliasPath;
TreeNode page = DocumentHelper.GetDocuments()
.Path( selectedPagePath )
.TopN( 1 )
var childrenNodes = DocumentHelper.GetDocuments<carouselslide>()
.WhereEquals( "NodeParentID", page.NodeID )
.Columns( "ImageSelector", "VideoLink", "Caption", "CaptionLocation" )
.OrderBy( "NodeOrder" )
foreach( var node in childrenNodes )
Slide slide = new Slide
Caption = node.Caption,
CaptionLocation = node.CaptionLocation,
ImageSelector = node.ImageSelector,
VideoLink = node.VideoLink
slides.Add( slide );
carousel.Header = properties.Header;
carousel.SubHeader = properties.SubHeader;
carousel.Slides = slides;
carousel.IsUsingArrows = properties.IsUsingArrows;
carousel.IsWhiteArrows = properties.IsWhiteArrows;
carousel.IsUsingButtons = properties.IsUsingButtons;
carousel.IsThreeSlideCarousel = properties.IsThreeSlideCarousel;
carousel.Id = properties.Id;
return PartialView( carouselWidget.ViewNameController, carousel );
Building clean reusable widgets and sections will speed up your development for future projects and give your content administrators the confidence to create the pages they need.