A critical vulnerability was discovered in React Server Components (Next.js). Our systems remain protected but we advise to update packages to newest version. Learn More

sunylcumar
May 12, 2025
  1105
(3 votes)

Creating a Dropdownlist in Optimizely CMS: Populate ISelectionFactory with values from another block's properties

Create a Block to hold selection options

using EPiServer.Cms.Shell.UI.ObjectEditing.EditorDescriptors;
using EPiServer.PlugIn;
using EPiServer.Shell.ObjectEditing;
using System.ComponentModel.DataAnnotations;
namespace MyApp.Models.Blocks
{
    [ContentType(DisplayName = "Select Options Block", Description = "")]
    public class SelectOptionsBlock : BlockData
    {
        [CultureSpecific]     
        [Display(Name = "Selection Options", Description = "List of options for the selection list.",  GroupName = SystemTabNames.Content, Order = 100)]
        [EditorDescriptor(EditorDescriptorType = typeof(CollectionEditorDescriptor<SelectionOption>))]
        public virtual IList<SelectionOption> SelectionOptions { get; set; }
    }

    public class SelectionOption
    {
        public string Text { get; set; }
        public string Value { get; set; }
    }

    [PropertyDefinitionTypePlugIn]
    public class SelectionOptionProperty : PropertyList<SelectionOption> { }

}

Create a page where you want to have the selection list and add the following 2 properties

namespace MyApp.Models.Pages
{
    [ContentType(DisplayName = "SelectionList Page", Description = "Page with a selection list populated from a block.", GroupName = SiteGroupNames.Specialized)]
    public class SelectionListPage : PageData
    {
        [CultureSpecific]
        [Display(Name = "Select Options Block", Description = "", GroupName = SystemTabNames.Content, Order = 1)]
        [AllowedTypes(typeof(SelectOptionsBlock))]
        public virtual ContentReference SelectOptionsBlockContent { get; set; }

        [CultureSpecific]
        [Display(Name = "Select List", Description = "",  GroupName = SystemTabNames.Content,  Order = 1)]
        [SelectOne(SelectionFactoryType = typeof(ItemSelectionFactory))]
        public virtual string SelectList { get; set; }
    }
}

Now create a selection list factory

using EPiServer.ServiceLocation;
using EPiServer.Shell.ObjectEditing;
using SVP.Models.Blocks;
namespace MyApp.Business.SelectionFactories
{
    public class ItemSelectionFactory : ISelectionFactory
    {
        public IEnumerable<ISelectItem> GetSelections(ExtendedMetadata metadata)
        {
            var loader = ServiceLocator.Current.GetInstance<IContentLoader>();
            var list = new List<SelectItem>();  
            dynamic contentMetadata = metadata;
            var ownerContent = contentMetadata.OwnerContent as IContent;            
            //create a dynamic object of current content type
            dynamic parentItem = ownerContent;
            //check if the block containing the select options is added to the current content (page or block)
            if (parentItem.SelectOptionsBlockContent != null)
            {
                //Get the block containing select options
                var optionsBlock = loader.Get<SelectOptionsBlock> parentItem.SelectOptionsBlockContent);
                //check if the optionsBlock has any items
                if (optionsBlock.SelectionOptions != null && optionsBlock.SelectionOptions.Count > 0)
                {
                    foreach (var listItem in optionsBlock.SelectionOptions)
                    {
                        list.Add(new SelectItem() { Text = listItem.Text, Value = listItem.Value });
                    }
                }
            }
            return list;
        }
    }
}

From the CMS, create a new block of type SelectOptionsBlock and add the necessary select options and publish it.

Select this newly created block in your page that you have created to have the selection list and publish the page.

May 12, 2025

Comments

El Magnifico
El Magnifico May 18, 2025 02:15 PM

Exellent example with full working source code.

Please login to comment.
Latest blogs
Building simple Opal tools for product search and content creation

Optimizely Opal tools make it easy for AI agents to call your APIs – in this post we’ll build a small ASP.NET host that exposes two of them: one fo...

Pär Wissmark | Dec 13, 2025 |

CMS Audiences - check all usage

Sometimes you want to check if an Audience from your CMS (former Visitor Group) has been used by which page(and which version of that page) Then yo...

Tuan Anh Hoang | Dec 12, 2025

Data Imports in Optimizely: Part 2 - Query data efficiently

One of the more time consuming parts of an import is looking up data to update. Naively, it is possible to use the PageCriteriaQueryService to quer...

Matt FitzGerald-Chamberlain | Dec 11, 2025 |

Beginner's Guide for Optimizely Backend Developers

Developing with Optimizely (formerly Episerver) requires more than just technical know‑how. It’s about respecting the editor’s perspective, ensurin...

MilosR | Dec 10, 2025