Loading...
Area: Optimizely CMS

Recommended reading 

Creating a page template using Web Forms

Create a page template in Visual Studio as follows:

  1. In the Solution Explorer, select the folder where you want to save the page template (in Web Forms, you can choose where to store it). Right-click and select Add new item from the context menu.
  2. Select the EPiServer node.
  3. Select the Page Template item and enter a name for the new template.
  4. Click OK.

Using the page templates

If you use a strongly-typed page type template, the template is automatically registered as a supported template for the specified page type (T). To make the template supported for all page types in the system, use EPiServer.Core.PageData as the generic type (T).

Use the [TemplateDescriptor] attribute on templates to add metadata to the template. You also can use the attribute to set the template as the default template for the page data. See the Attributes article for information about the TemplateDescriptor attribute.

You can use several [TemplateDescriptor] attributes on the same template to specify several page types that have the template as a supported renderer. When the template is strongly typed, you must derive the ModelType type from the generic type. If two page types use one template, you can use the multi-attribute functionality by setting the generic type to PageData and add two [TemplateDescriptor] attributes, which specifies the types in the ModelType property.

C#
using EPiServer;
using EPiServer.Core;
using EPiServer.DataAnnotations;
using EPiServer.Framework.DataAnnotations;
using EPiServer.SpecializedProperties;
using EPiServer.Web;

[ContentType]
public class MyPage : PageData
{
    public virtual XhtmlString MainBody { get; set; }
    public virtual PageList MainList { get; set; }
}

[TemplateDescriptor(Name = "My template", Description = "My first template", Path = "~/templates/MyTemplate.aspx", Default = true)]
public partial class MyTemplate : TemplatePage<MyPage>
{ }

Creating a block control using Web Forms

Create a block template in Visual Studio as follows:

  1. In the Solution Explorer context menu, select Add new item.
  2. Select the EPiServer node.
  3. Select the Block Template and enter a name for the new template.

The template is automatically registered as a supported template for the specified block type (T). Use the EPiServer.Core.BlockData as the generic type (T) to make the template supported for all block types in the system.

Use the [TemplateDescriptor] attribute, which is in the EPiServer.Framework.DataAnnotations namespace, on controls to add meta data to the template. You also can us the attribute to set the control as the default template for the block data. The attribute contains the following properties:

  • Path. The path to the template to be rendered. Set the path if the folder structure does not follow namespace structure because a namespace convention searches for a file the path according to the namespace. For example, if there is a usercontrol with type CodeSamples.Templates.Units.MyBlockControl then the Path is resolved if it is located in a folder structure that follows the namespace. So if there is a Templates folder in the application root and it has a sub-folder Units where the file MyBlockControl.ascx is located then the Path is found and hence Path does not need to be set.
  • ModelType. The block data type. It can be used when several [TemplateDescriptor] attributes are used on the same control, to specify several block types which will have the control as a supported render. The ModelType type must be derived from the generic type.
  • Default. Defines the control as the default control for the block data type.
  • Name. The name of the control.
  • Description. A summary of the control.
  • Inherited. When this property is set to true, block data types that inherit from the ModelType type or Generic type get the control as a supported control.
C#
using EPiServer;
using EPiServer.Core;
using EPiServer.DataAnnotations;
using EPiServer.Framework.DataAnnotations;
using EPiServer.SpecializedProperties;
using EPiServer.Web;

[ContentType(DisplayName = "A page list", Description = "A block of properties needed to display a page list")]
public class PageList : BlockData
{
    public virtual PageReference Root { get; set; }
    public virtual int Count { get; set; }
    public virtual string Heading { get; set; }
}

[TemplateDescriptor(Name = "My block control", Description = "My first block control", Path = "~/templates/MyBlockControl.ascx", Default = true)]
public partial class MyBlockControl : BlockControlBase<PageList>
{ }

Creating a page template using MVC

Basic template

To render an MVC view for a page type, create a controller that inherits from EPiServer.Web.Mvc.PageController<T>, where T is your page type. This controller is called for the page type, if it is chosen as the renderer for the page type. To render EPiServer CMS properties, use the Html.PropertyFor extension method, which calls another view that has the same name as the property type you are about to render. EPiServer has views for built-in properties that render the properties, as shown in the following example.

C#
public class AcmeStandardPageController : PageController<MyStandardPage>
{
    public ActionResult Index()
    {
        return View();
    }
}

[ContentType]
public class MyStandardPage : PageData
{
    public virtual string MyText { get; set; }
}

You can use the HTML helpers in the EPiServer.Web.Mvc.Html namespace as an alternative to Html.PropertyFor. The HTML helpers are called through Html.DisplayFor, but you can use them directly.

  • Html.CategoryList
  • Html.Fragment
  • Html.PageLink
  • Html.UrlLink
  • Html.XForm
  • Html.RenderXForm
  • Html.BeginXForm
  • Html.EndXForm
  • Html.XhtmlString
  • Html.RenderXhtmlString

Dynamic content

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. 

    C#
    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();
                }
            }
        }
    }
    C#
    @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.
    C#
    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.

XForms

To render an XForm property on a page, use the Property and RenderPropertyXForm HTML helper methods in the view. The Property method uses the default behavior, while the RenderPropertyXForm takes the name of the property, and an XFormParameters class as parameters. Optionally use the XFormParameters parameter to override the default settings.

If you do not set the SuccessAction and FailedAction properties on the XFormParameters class, the system uses default views for successful and failed posts. If you set SuccessAction to Success and FailedAction to Failed, the system calls the Success or Failed action in the controller, depending on whether a validation error occured when posting the form. You must create the Success and Failed methods in the controller to make it work.

C#
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%@ Import Namespace="EPiServer.XForms.Util" %>

<section id="form">
    <%--<% Html.EnableClientValidation(); %>--%>
    <%: Html.ValidationSummary() %>
    <% Html.RenderPropertyXForm("XForm", new XFormParameters() { SuccessAction = "Success", FailedAction = "Failed" }); %>
    <%--<%: Html.Property("XForm") %>  --%>
</section>

Configuration

For EPiServer CMS to match a requested URL to a controller, the EPiServer.Web.HierarchicalUrlRewriteProvider class must be in use, which is the default URL rewrite provider in a newly installed site. For an upgrade, you must change the configuration manually.

Creating a block control using MVC

You can render an MVC view for a block type in the following ways:

  • Create a controller that inherits from EPiServer.Web.Mvc.BlockController<TBlockData>, where TBlockData is your block type. The system calls this controller for the block type, if it is chosen as the renderer of the block type. EPiServer.Web.Mvc.BlockController<TBlockData>  has an implementation of the action Index, which calls a partial view with the same name as the block type.
  • Create a partial view with the same name as the block type. If the view is chosen as the renderer of the block type, the view is called with the page data object directly, without controller involvement.

To render EPiServer CMS properties, use the procedure as you do on pages described in this topic.

Managing client resources when you develop templates

To require rendering of certain client resources on the page in a specific area, see the requirements for templates to support this in Managing client resources in EPiServer CMS.

Do you find this information helpful? Please log in to provide feedback.

Last updated: Feb 23, 2015

Recommended reading