Create EPiServer dynamic content with advanced settings

This article was migrated from an older iteration of our website, and it could deviate in design and functionality.


This post explains how to use a user control for presenting a user interface to an editor when inserting dynamic content.

Estimated read time : 10 minutes

Jump to

Editor settings for dynamic content in EPiServer

I previously published a post on creating new dynamic content in EPiServer which used a PropertyDataCollection object to specify settings properties for the dynamic content. For trivial cases this is often enough for the editor to specify how the dynamic content should look or behave. However, for more complex settings, you may find it more useful to use a user control for providing the editor with a user interface for configuring the dynamic content.

Create the business type

The dynamic content we’ll create will be used to present a collection of slides which consist of a thumbnail, a full-size image, a title, and some additional content text. So, I add a business class for storing data for a single slide:

image

It’s a really trivial serializable class with four properties (I use the XmlRoot and XmlElement attributes to have more control over the serialized XML):

[Serializable]
[XmlRoot("slide")]
public class FeatureSlide
{
    [XmlElement("image")]
    public string ImageUrl { get; set; }
 
    [XmlElement("thumbnail")]
    public string ThumbnailUrl { get; set; }
 
    [XmlElement("title")]
    public string Title { get; set; }
 
    [XmlElement("content")]
    public string Html { get; set; }
}

Create the rendering user control

First I create the user control which will be used to render the dynamic content in page templates:

image

Since it will render a collection of slides I add a public property to it:

public partial class FeatureSlideShow : System.Web.UI.UserControl
{
    public IEnumerable<FeatureSlide> Slides { get; set; }
}

The actual HTML and JavaScript for the slideshow is outside the scope of this post, but obviously the FeatureSlideShow user control renders everything needed for a slick slide show on a page template. :)

Create the dynamic content type

Next I create my dynamic content type

image

…and I make it inherit the IDynamicContent interface:

public class FeatureSlideShow : IDynamicContent

Whenever the dynamic content is loaded as part of a page template we want it to be rendered using the user control we created earlier:

public class FeatureSlideShow : IDynamicContent
{
    public System.Web.UI.Control GetControl(EPiServer.PageBase hostPage)
    {
        var userControl = (UserControls.FeatureSlideShow)hostPage.LoadControl("/Templates/UserControls/FeatureSlideShow.ascx");
        userControl.Slides = TemplateFoundation.Serialization.XmlSerializer.Deserialize<List<FeatureSlide>>(State);
        return userControl;
    }
 
    public EPiServer.Core.PropertyDataCollection Properties
    {
        get { throw new NotImplementedException(); }
    }
 
    public string Render(EPiServer.PageBase hostPage)
    {
        throw new NotImplementedException();
    }
 
    public bool RendersWithControl
    {
        get { return true; }
    }
 
    public string State { get; set; }
}

We make the RendersWithControl property return true since we do use a control for rendering the dynamic content (meaning we don’t have to implement the Render method since we return a control through the GetControl method).

Note that we set the Slides property of the user control before returning it in order to specify the content (ie slides) it should render (by deserializing the value of the dynamic content’s State property, more on that in a bit).

We skip implementing the Properties property since we will use a separate user control to render the user interface the editor will use to specify the dynamic content settings.

Create the user control for configuring the dynamic content

I add a new user control which will present a user interface to the editor when inserting or editing the dynamic content…

image

…and I make the user control inherit the DynamicContentEditControl base class:

public partial class FeatureSlideShowEditor : DynamicContentEditControl

Configure the dynamic content type to use the user control for editor settings

In order to make our dynamic content type use our newly created user control for editing the settings we add a GuiPlugIn attribute to our dynamic content class:

[GuiPlugIn(
    Url = "~/Templates/DynamicContent/FeatureSlideShow/FeatureSlideShowEditor.ascx", 
    Area = PlugInArea.DynamicContent)]
public class FeatureSlideShow : IDynamicContent

Now, whenever an editor inserts or edits the dynamic content the user control will be rendered (everything inside “Settings” comes from our user control):

image

Persisting the data for our dynamic content

The data (such as settings specified by an editor) for dynamic content is persisted through the dynamic content’s State property. It’s essentially a string value, and since we want to store some slightly more complex data in it we use XML serialization to be able to store our collection of slides as a string.

Since the editor user control we created inherits DynamicContentEditControl we can access the associated dynamic content object through a property called Content, and subsequently access its State property.

In order to have the correct State value be set when the editor is finished inserting or editing the dynamic content, we implement the PrepareForSave method:

public override void PrepareForSave()
{
   // Serialize the list of slides to XML and store it in the dynamic content's State property
   Content.State = TemplateFoundation.Serialization.XmlSerializer.Serialize(Slides);
}

In this case we use the static XmlSerializer class which is part of EPiServer Template Foundation to make it easy to serialize/deserialize our slides.

Note that you may want to use Base64 encoding when setting the State property. If you do, you can use this code snippet for converting a string to and from Base64 encoding.

Other resources

Allan Thraen (product owner of EPiServer CMS) has published a small addon package for working with dynamic content in EPiServer CMS 5 R2 and later. For one it enables dynamic content to be registered programmatically without having to worry about modifying web.config.

Update: As you probably know the EPiServer UI only supports Internet Explorer and Firefox. Google Chrome works fairly well most of the time, but one thing it does not support is editing existing dynamic content. Changes to the State value of existing dynamic content simply will not persist in Chrome (I think it has to do with how it is stored as part of the markup in an XHTML property, possibly because of how the TinyMCE plugin woks).