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.
Before you start
This guide requires the following:
- Familiarity with C#, .NET Core, Dependency injection, and the MVC pattern.
- A running instance of Xperience by Kentico, preferably 29.6.1 or higher.Some features covered in the Training guides may not work in older versions.
- Basic knowledge of the Page Builder in Xperience by Kentico.
Code samples
You can find a project with completed, working versions of code samples from this guide and others in the finished branch of the Training guides repository.
The main branch of the repository provides a starting point to code along with the guides.
The code samples in this guide are for .NET 8 only.
They come from a project that uses implicit using directives. You may need to add additional using
directives to your code if your project does not use this feature.
For a finished example implementation, take a look at the DropdownEnumOptionsProvider.cs file. 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.
First, 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.
Then 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 theLandingPageTemplateProperties.cs
file in TrainingGuides.Web/Features/LandingPages
. The dropdown values are currently defined by a string constant:
...
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";
...
LandingPageHeadingTypeOption
enumeration accordingly.
using System.ComponentModel;
...
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 the DataProviderType
property of the DropDownComponent
.
Next, 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;
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.