Add a custom dropdown provider for administration components
When editors create pages with Page Builder, they utilize components (page templates, sections, widgets), prepared by the developers. Each component has properties, that editors set in the Xperience administration using UI controls, for example, a dropdown selector.
As a developer, you can populate an Xperience dropdown selector with data in two ways:
Pass a “hardcoded” string of options, as you can see in this example.
Create a dropdown provider that maps options dynamically.
This guide covers the second approach. In our example, we use enumeration to define the dropdown options.
Setting up dropdown mapping is an important building block for the later guides in this Page Builder series, which use dropdown components heavily.
Prerequisites
This guide assumes you have:
- basic knowledge of C# and .NET framework concepts
- familiarity with the basics of Page Builder in Xperience by Kentico
If you’d like to follow along with the example discussed in this guide, the main branch of our training guides repository is a great starting point.
If you are working on your own project, make sure your instance of Xperience by Kentico is version 29.2.0 or higher.
For a finished example implementation, take a look at the DropdownEnumOptionsProvider.cs file in the finished branch of our training guides repository.
To see this provider in action, check out LandingPageTemplateProperties.cs file in the same repo.
Implement a generic mapper class
The Xperience Dropdown selector has aDataProviderType
property that can take a class, mapping a custom enumeration to specific dropdown options.While it is viable to implement a custom class per enumeration, a reusable generic class will save you time and lines of code.
Create a generic
DropdownEnumOptionProvider
class that:- implements
IDropDownOptionsProvider
- accepts
struct
andEnum
as the generic type
If you are working in the training guides repository, we recommend placing the class inside ~/Features/Shared/OptionProviders folder in the TrainingGuides.Web project.- implements
Implement the following methods:
GetOptionItems
- tells Xperience how to map the enumeration members to dropdown items.
Parse
- casts a
string
value to the enumeration type. The value from the dropdown selector control comes back asstring
by definition, so the method will come in handy later in your code.
- casts a
To work with enumerations, this guide’s example uses EnumsNET NuGet package. The library allows you to access the enumeration attributes, like Description, which is handy, for example, to store UI labels for each dropdown option.
Below is a complete code of a generic DropdownEnumOptionProvider
class, for your reference:
using System.ComponentModel;
using EnumsNET;
using Kentico.Xperience.Admin.Base.FormAnnotations;
namespace TrainingGuides.Web.Features.Shared.OptionProviders;
public class DropdownEnumOptionProvider<T> : IDropDownOptionsProvider
where T : struct, Enum
{
public Task<IEnumerable<DropDownOptionItem>> GetOptionItems()
{
// map enum members to DropDownOptionItem
var results = Enums.GetMembers<T>(EnumMemberSelection.All)
.Select(enumItem =>
{
// dropdown item label:
// if available, use Description attribute, otherwise use enum item name
string text = enumItem.Attributes
.OfType<DescriptionAttribute>()
.FirstOrDefault()?.Description
?? enumItem.Name;
// dropdown item value
string value = enumItem.Value.ToString();
return new DropDownOptionItem { Value = value, Text = text };
});
return Task.FromResult(results.AsEnumerable());
}
public virtual T Parse(string value, T defaultValue) =>
Enums.TryParse<T>(value, true, out var parsed)
? parsed
: defaultValue;
}
Use the new mapper class
Let’s demonstrate the enumeration mapping on an existing dropdown selector property of the Landing page template in the main branch of our training guides repository.
If you are working on your own project, feel free to define a property and enumeration values that fit your use case. You will still be able to follow most of the steps below.
Define your enumeration
- Examine the
LandingPageTemplateProperties.cs
file inTrainingGuides.Web/Features/LandingPages
. The dropdown values are currently defined by a string constant:C#LandingPageTemplateProperties.cs - BEFORE MAPPING... private const string OPTIONS = "H1;Heading 1" + "\n" + "H2;Heading 2" + "\n" + "H3;Heading 3" + "\n" + "H4;Heading 4" + "\n" + "P;Paragraph" + "\n"; [DropDownComponent( Label = "Message tag type", Options = OPTIONS, ExplanationText = DESCRIPTION)] public string MessageType { get; set; } = "H4"; ...
- Define the
LandingPageHeadingTypeOption
enumeration accordingly.C#public enum LandingPageHeadingTypeOption { [Description("Heading 1")] H1, [Description("Heading 2")] H2, [Description("Heading 3")] H3, [Description("Heading 4")] H4, [Description("Paragraph")] P }
Each enumeration item should match one option in the dropdown component.
The Description of each item is what editors will see as labels in the Xperience administration. If you don’t define a Description attribute, the item’s name becomes the label by default.
Map the enumeration to the dropdown component
- Assign the type of
DropdownEnumOptionProvider<YOUR_ENUMERATION>
to theDataProviderType
property of theDropDownComponent
. - Remove the
Options
property, which is no longer needed.
LandingPageHeadingTypeOption
enumeration mapped to the MessageType
dropdown property.
using System.ComponentModel;
using Kentico.PageBuilder.Web.Mvc.PageTemplates;
using Kentico.Xperience.Admin.Base.FormAnnotations;
using TrainingGuides.Web.Features.Shared.OptionProviders;
using TrainingGuides.Web.Features.Shared.OptionProviders.Heading;
namespace TrainingGuides.Web.Features.LandingPages;
public class LandingPageTemplateProperties : IPageTemplateProperties
{
private const string DESCRIPTION = "Select the type of Html tag that wraps the home page message";
[DropDownComponent(
Label = "Message tag type",
ExplanationText = DESCRIPTION,
DataProviderType = typeof(DropdownEnumOptionProvider<LandingPageHeadingTypeOption>)
)]
public string MessageType { get; set; } = nameof(LandingPageHeadingTypeOption.H2);
}
// enumeration defining the dropdown values and labels
public enum LandingPageHeadingTypeOption
{
[Description("Heading 1")]
H1,
[Description("Heading 2")]
H2,
[Description("Heading 3")]
H3,
[Description("Heading 4")]
H4,
[Description("Paragraph")]
P
}
If you followed along with the example above, run the TrainingGuides.Web project. When you edit the Home page template in the Xperience administration, the Message tag type property should let you change the style of the “Welcome to Training guides!” message - the same way as before the refactor.
What’s next
You can now utilize the DropdownEnumOptionProvider
class across your project, for dropdown selector properties of page templates, Page Builder sections, or widgets alike. As later guides in this series demonstrate, you can work with enumerations that are shared or reuse other enumeration values.
If you have been following along using the the training guides repository, take a look at the Landing page view in the finished branch. You’ll notice it utilizes a tag helper rather than an in-template logic you can see in your code. Enumeration option providers and this scenario are both well-suited to this kind of extraction.
Note, that not all Xperience UI form components have the DataProviderType
property and support the dynamic data source.
If you’d like to read more about how to approach working with Page Builder in Xperience by Kentico projects, Meet business requirements with Page Builder provides a great introductory explanation.
The next guide of this series will walk you through the process of creating versatile page templates.