Create Feeds for Options in Optimizely CMS Form Selection Element

Create Feeds for Options in Optimizely CMS Form Selection Element

In this blog post we are going to cover how we can use a feed to render the options of a form selection element so it can be used in an Episerver Form. So without further due, lets begin.

First, we will create a country selection element block for Optimizely CMS Forms, this element will inherit from the Selection element block base class and use the Country Feed to get all the different values needed, the feed is set in the constructor of the class.

[ContentType(
    DisplayName = "Country Selection Block",
    GUID = "{948224EA-D34E-496A-BA01-32F9DF667712}",
    GroupName = "Custom Elements")]
public class CountrySelectionElementBlock : SelectionElementBlockBase<OptionItem>
{
    [Editable(false)] public override string Feed { get; set; }

    public override void SetDefaultValues(ContentType contentType)
    {
        base.SetDefaultValues(contentType);
        Feed = new CountryFeed().ID;
    }

    public override string GetDefaultValue() => GeoPositionHelper.GetCurrentUserCountry();
}

Then, we will create a helper which will allow us to define a default value for the selection element, we will use en-US, but you can get the current user country from the IP or from another method; and methods to get the list of countries to be displayed in the selection element which you can modify to something more dynamic.

public static class GeoPositionHelper
{
    public static List<IFeedItem> GetCountryFeedItems()
    {
        var optionItems = new List<IFeedItem>();
        optionItems.AddRange(from entry in GetCountryList()
                             orderby entry.Item1
                             let item = new FeedItem { Key = $"{entry.Item1}", Value = $"{entry.Item2}" }
                             select item);

        return optionItems;
    }

    public static List<Tuple<string, string>> GetCountryList()
    {
        return new List<Tuple<string, string>>()
        {
            new("United States", "en-US"),
            new("Mexico", "es-MX"),
            new("Spain", "es-SP"),
            new("Canada", "en-CA")
        };
    }

    public static string GetCurrentUserCountry()
    {
        var location = "US"; // You can get user location from ip
        var englishCountry = new RegionInfo($"en-{location}")?.EnglishName;

        return !string.IsNullOrEmpty(englishCountry) ? englishCountry : "";
    }
}

Finally, we will create the feed class which implements the IFeed interface and IUEntityInEditView and is registered as a Feed service type. We use the helper defined above to get the items and render them in the form. Be careful with the ID which must be unique.

[ServiceConfiguration(ServiceType = typeof(IFeed))]
public class CountryFeed : IFeed, IUIEntityInEditView
{
    public IEnumerable<IFeedItem> LoadItems()
    {
        var feedItems = new List<IFeedItem>();

        feedItems.AddRange(GeoPositionHelper.GetCountryFeedItems());

        return feedItems;
    }

    public string ID { get; set; } = "7587F9F8-D41A-49C6-8618-5E67CDAF85D9";

    public string Description { get; set; } = "Country List";

    public string ExtraConfiguration { get; }

    public string EditViewFriendlyTitle => Description;

    public bool AvailableInEditView => true;
}

Now, you can add a country selection form to any Optimizely form as you do for any other form element

And when you render the form, it will be populated with the values defined in the feed.

And that is it. You can now render a list of items in a form selection element which can be as dynamic as you need it to be. If you have any questions or suggestions please let me know in the comments. I hope this can help someone and as always keep learning !!!

Written by:

Jorge Cardenas

Developer with several years of experience who is passionate about technology and how to solve problems through it.

View All Posts

Leave a Reply