November Happy Hour will be moved to Thursday December 5th.
November Happy Hour will be moved to Thursday December 5th.
Product version: |
EPiServer CMS 6 R2 |
---|---|
Document last saved: |
This technical note contains functional and technical information for the EPiServer CMS Dynamic Content functionality.
EPiServer CMS Dynamic Content allows developers to create blocks of functionality in code which can then be utilized later by an editor on a page in the HTML editor. This means editors are no longer restricted to working with static content and can make their pages more interactive. A dynamic content class can be thought of as a cut down version of an EPiServer template page, the implementation doesn't define a whole page, rather just a small section of it. A nice analogy would be a .NET UserControl, which in fact can be used to implement the user interface of a dynamic content object.
In EPiServer CMS 6 R2 we have introduced a new class attribute that simplifies the development and registration of a Dynamic Content class. One benefit of using the DynamicContentPlugin attribute is that you eliminate the need to manually register your Dynamic Content class in episerver.config. Only cflasses that implement EPiServer.DynamicContent.IDynamicContent may be decorated with this attribute, otherwise the application will throw an exception during startup. However, decorated classes that derive from System.Web.UI.Control will implicitly implement IDynamicContent.
DisplayName and Description
As with any other plugins, DisplayName is a string used to identify the plugin in lists and Description is a short text that describes what the Dynamic Content type does.
Url, UrlFromUI, UrlFromUtil
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, i.e. use UrlFromUI if the control is located somewhere below the UI folder. The UrlFromUI and UrlFromUtil attributes require relative urls and the Url attribute should have a application relative url (~/SomeFolder/MyEditControl.ascx).
If you develop your Dynamic Content plugin as a Control you may choose to not define values for any of the Url attributes, this causes the application to automatically generate a control for editing your Dynamic Content settings.
ViewUrl
The path to the user control used to render the Dynamic Content type for visitors. This url can point to the Dynamic Content plugin itself provided it is implemented as a User Control.
The IDynamicContent interface is the fundamental building block of a dynamic content class. This interface is implicitly used when you make use of the DynamicContentPlugIn attribute but its use is automatic and hidden from you. The interface's methods and properties are explained below.
string Render(PageBase hostPage)
The Render method should return the XHTML output to display on the page. This is what the visitor actually sees when they visit the page the object is being rendered on. The hostPage reference can be null as this method can be called by EPiServer without a page in context. This method should return null or an empty string if the class delegates rendering to a control.
System.Web.UI.Control GetControl(PageBase hostPage)
The GetControl method should return a reference to a control if the dynamic content class wishes to delegate its rendering responsibilities. The control returned can be anything that derives from control including web controls, user controls and custom controls. Null should be returned if the class handles it's own rendering via the Render method.
bool RendersWithControl { get; }
Return true if the class delegates rendering to a control, false otherwise.
string State { get; set; }
Get and set the state string for an instance. The class should use this value to serialize and deserialize its internal state. This can be null or an empty string.
PropertyDataCollection Properties { get; }
Get a collection of EPiServer properties that should be presented in the editing inteface. The properties within the collection should be members of the plug in class so that the values entered from the editing interface can be consumed.
Here's an example of a class inheriting from UserControl that is decorated with the DynamicContentPlugIn attribute. Since our class inherits from UserControl we do not have to implement IDynamicContent - an implicit implementation of IDynamicContent is automatically generated based on the settings of the DynamicContentPlugIn attribute and the class' public properties.
Note that the value of ViewUrl is an application relative url that points to the markup file of the control, this means that the rendering of the Dynamic Content for visitors is handled by the control itself.
Note also that no edit interface url (Url, UrlFromUI, UrlFromUtil) has been specified here, this means that an edit interface will automatically be generated based on the public properties of the class. Only properties of the following types that have public getters and setters will be included in the edit interface:
[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 markup of the user control is very basic and is just for illustrational purposes:
<%# MyString %>
<%# MyInt %>
<%# MyBool %>
<%# MyPageReference %>
<%# MyPropertyString %>
Because the class is decorated with the DynamicContentPlugIn attribute the plugin is automatically registered and ready for use when the application starts. Here is a look at what the editing interface looks like for the plugin:
And here is how the output looks for a visitor:
This section contains an example of how to create a dynamic content plugin by implementing the IDynamicContent interface. With the addition of the DynamicContentPlugIn in EPiServer CMS6 R2 the following way of creating a dynamic content class will probably become less popular.
Note that this example still makes use of the DynamicContentPlugIn attribute, but only for registering the plugin. If you wish you can remove attribute and instead register your plugin by following the instructions in the Registering Dynamic Content with EPiServer CMS chapter.
[DynamicContentPlugIn(
DisplayName = "ClassDynamicContentPlugin",
Description = "Example of a Dynamic Content plugin as a simple class.")]
public class ClassDynamicContentPlugin : IDynamicContent
{
// Some properties for holding the state.
private PropertyString _myPropertyString;
private PropertyNumber _myPropertyNumber;
private PropertyDataCollection _myProperties;
// Initialize the properties.
public ClassDynamicContentPlugin()
{
_myPropertyString = new PropertyString();
_myPropertyString.Name = "MyPropertyString";
_myPropertyNumber = new PropertyNumber();
_myPropertyNumber.Name = "MyPropertyNumber";
_myProperties = new PropertyDataCollection();
_myProperties.Add(_myPropertyString);
_myProperties.Add(_myPropertyNumber);
}
#region IDynamicContent Members
// We do not use a separate rendering control.
public bool RendersWithControl
{ get { return false; } }
public Control GetControl(PageBase hostPage)
{ return null; }
// Simple render method that only writes the values
// of our properties within a div tag.
public string Render(PageBase hostPage)
{ return String.Format("<div>{0}</div>", State); }
// Calles by the editing interface, returns a collection with the
// properties we wish to be editable.
public PropertyDataCollection Properties
{ get { return _myProperties; } }
// Very simple de/serialization of the state.
public string State
{
get
{
return String.Format("{0},{1}",
_myPropertyString.ToString(), _myPropertyNumber.ToString());
}
set
{
string[] values = value.Split(',');
_myPropertyString.Value = values[0];
_myPropertyNumber.ParseToSelf(values[1]);
}
}
#endregion
}
If you use the DynamicContentPlugIn attribute you do not need to manually register your plugin in this way. If you don't use the attribute you need to register the plugin in episerver.config in the following way:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<episerver xmlns="http://EPiServer.Configuration.EPiServerSection">
<dynamicContent>
<controls>
<add description="My example dynamic content class"
name="ExampleDynamicContent"
type="MyNamespace.MyDynamicContent, MyDll" />
</controls>
</dynamicContent>
</episerver>
</configuration>
When the EPiServer CMS rendering code comes across a dynamic content tag in a XHTML string property, it will try and create an instance of the dynamic content class referred to, it will then call the object's State property to initialize it. After this it checks if the object delegates it's rendering to a control by calling the RendersWithControl property. If this property is true then the GetControl method will be called to obtain the rendering control, otherwise if false then the objects Render method is called to obtain the XHTML output. The placeholder span tag in the HTML output stream is then replaced by the output generated by the dynamic content object or delegate control so the person visiting your site can see the fruits of your labor.