Create a plug-in
Describes how to create a plug-in for dynamic content using the DynamicContentPluginAttribute and how to add support for MVC to a plug-in.
Caution
Dynamic content is deprecated in Optimizely Content Management System (CMS 12). Use blocks instead. While existing solutions will continue to work, you should not build new solutions on this API. It will be phased out in the future.
The DynamicContentPluginAttribute simplifies the development and registration of a dynamic content class by eliminating manual registration of your dynamic content class in the <episerver>
section of web.config
.
Note
Only classes that implement EPiServer.DynamicContent.IDynamicContentBase may be decorated with this attribute, otherwise the application generates an error during startup. However, decorated classes that derive from
System.Web.UI.Control
implicitly implementIDynamicContent
.
-
DisplayName
is a string used to identify the plug-in in lists.Description
is a short text that describes what the dynamic content type does.
-
Url, UrlFromUi, and UrlFromUtil
Url
specifies the path to the user control that handles editing of the dynamic content type. You only have to provide one of these values, choose the attribute that best matches the location of your editing control, useUrlFromUi
if the control is located somewhere below the UI folder. TheUrlFromUi
andUrlFromUtil
attributes require relative URLs, and theUrl
attribute should have an application-relative URL (~/SomeFolder/MyEditControl.ascx
).If you develop your dynamic content plug-in as a Control, you may choose not to define values for any of the URL attributes. This causes the application to automatically generate a control for editing your dynamic content settings.
-
ViewUrl
ViewUrl specifies the path to the user control used to render the dynamic content type for visitors. This URL can point to the dynamic content plug-in if you implement it as a user control.
The following example shows a class inheriting from UserControl
that is decorated with the DynamicContentPlugInAttribute. Because the class inherits from UserControl
you do not have to implement any interfaces, an implicit implementation of IDynamicContentControl
is automatically generated based on the settings of the DynamicContentPlugInAttribute
and the class public properties.
The value of ViewUrl
is an application relative URL pointing to the control's markup file; the control handles the rendering of the Dynamic Content for visitors.
No edit interface URL (Url
, UrlFromUI
, UrlFromUtil
) was specified, so an editorial interface is automatically generated based on the public properties of the class. Only properties of the following types that have the public get and set included in the editorial interface:
- System.Int32
- System.String
- System.Bool
- EPiServer.Core.PageReference
- Types derived from EPiServer.Core.PropertyData
[DynamicContentPlugIn(
DisplayName = "UserControlDynamicContentPlugin",
Description = "Example of a Dynamic Content plugin as a user control.",
ViewUrl = "~/Examples/UserControlDynamicContentPlugin.ascx")]
public partial class UserControlDynamicContentPlugin: UserControl {
// Properties of the following basic types that have public getters
// and setters are supported by the autogenerated edit interface.
public string MyString {
get;
set;
}
public int MyInt {
get;
set;
}
public bool MyBool {
get;
set;
}
// The same is true for EPiServer.Core.PageReference...
public PageReference MyPageReference {
get;
set;
}
// ...and types inheriting from EPiServer.Core.PropertyData,
// illustrated here with PropertyString.
public PropertyString MyPropertyString {
get;
set;
}
protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
DataBind();
}
}
}
The basic markup of the user control in the following example is just for illustration purposes.
<%# MyString %>
<%# MyInt %>
<%# MyBool %>
<%# MyPageReference %>
<%# MyPropertyString %>
Because the class is decorated with the DynamicContentPlugInAttribute
, the plug-in is automatically registered and ready for use when the application starts. The following example shows the plug-in in the editorial interface.
The following example shows the output for a visitor.
string 8 False 1 PropertyString
Add MVC support for a dynamic content plug-in
You can make a dynamic content plug-in support MVC in the following ways:
-
Create a display template with the same name as the dynamic content plug-in.
For theÂ
DynamicPageProperty
 plug-in, the name isÂDynamicPageProperty.ascx
 orÂDynamicPageProperty.cshtml
. The view takes the dynamic content plug-in as the view model and renders the dynamic content in view mode. The following example shows a simple dynamic content (DdsViewerDynamicContent
), and a razor view for rendering the content.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using EPiServer.DynamicContent;
using EPiServer.PlugIn;
using EPiServer.Data.Dynamic;
using EPiServer.Core;
namespace CodeSamples.Additional_Content.HowTo {
/// <summary>
/// Dynamic content showing the first 100 items in a Dynamic Data Store.
/// A specific editor is used to select store.
/// </summary>
[GuiPlugIn(Url = "~/EPiServer/DynamicContent/DdsViewerDynamicContentEdit.ascx", Area = PlugInArea.DynamicContent)]
public class DdsViewerDynamicContentUsingRazor: IDynamicContentBase {
/// <summary>
/// Gets and sets the selected store
/// </summary>
public string State {
get;
set;
}
/// <summary>
/// This property is not used, because a specific editor is used.
/// </summary>
public PropertyDataCollection Properties {
get {
return null;
}
}
/// <summary>
/// Gets the first 100 hits from the selected store
/// </summary>
public IEnumerable<PropertyBag>Top100 {
get {
return DynamicDataStoreFactory.Instance.GetStore(State).ItemsAsPropertyBag().Take(100).ToList();
}
}
}
}
@using CodeSamples.Additional_Content.HowTo
@model DdsViewerDynamicContent
<h2>Store: @Model.State</h2>
<table>
@if (@Model.Top100.Count() > 0) {
<tr>
@foreach (string column in @Model.Top100.First().Keys) {
<th>@column</th>
}
</tr>
}
@foreach (var propertyBag in @Model.Top100) {
<tr>
@foreach (var value in propertyBag.Values) {
<td>@value</td>
}
</tr>
}
</table>
- Let the plug-in implement the interfaceÂ
System.Web.Mvc.IView
, which is exactly what theÂDynamicPageProperty
 does. The interface only contains the methodÂRender
, with aÂViewContext
 object and aÂTextWriter
.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using EPiServer.DynamicContent;
using EPiServer.PlugIn;
using EPiServer.Data.Dynamic;
using System.IO;
using System.Web.Mvc;
using EPiServer.Core;
namespace CodeSamples.Additional_Content.HowTo {
/// <summary>
/// Dynamic content showing the first 100 items in a Dynamic Data Store.
/// A specific editor is used to select store.
/// </summary>
[GuiPlugIn(Url = "~/EPiServer/DynamicContent/DdsViewerDynamicContentEdit.ascx", Area = PlugInArea.DynamicContent)]
public class DdsViewerDynamicContentUsingIView: IDynamicContentBase, System.Web.Mvc.IView {
/// <summary>
/// Gets and sets the selected store
/// </summary>
public string State {
get;
set;
}
/// <summary>
/// This property is not used, because a specific editor is used.
/// </summary>
public PropertyDataCollection Properties {
get {
return null;
}
}
/// <summary>
/// Gets the first 100 hits from the selected store
/// </summary>
public IEnumerable<PropertyBag> Top100 {
get {
return DynamicDataStoreFactory.Instance.GetStore(State).ItemsAsPropertyBag().Take(100).ToList();
}
}
/// <summary>
/// Renders the data received from the selected store
/// </summary>
/// <param name="context">The context.</param>
/// <param name="writer">The writer.</param>
public void Render(ViewContext context, TextWriter writer) {
foreach(PropertyBag propertyBag in Top100) {
foreach(var value in propertyBag) {
writer.Write(value);
}
}
}
}
}
- If there is a display template with the same name as the dynamic content plug-in, and the plug-in implementsÂ
IView
, the system calls the display template and ignores the IView implementation.
Updated 6 months ago