November Happy Hour will be moved to Thursday December 5th.

Loading...
Area: Optimizely CMS
ARCHIVED This content is retired and no longer maintained. See the latest version here.

Recommended reading 
  • page type defines a set of properties, for example page name and publish date.
  • page is an instance of the .NET class defining the page type. When a page is created in edit view, values are assigned to the properties, and stored in the database.
  • The controller and view fetches the stored property values and renders the output.
  • template can be associated with the page type, to render the output in a certain context.

In the following you will find examples of how to work with page types and associated controllers, views and templates for rendering the content.

Page types

In Episerver, page types are usually defined in code as classes based on a model inheriting from EPiServer.Core.PageData. A PageData object is the programmatic representation of a page, containing the properties defined in your .NET class. The value of currentPage is automatically set to the PageData object that is requested by the client. During initialization, the bin folder is scanned for .NET classes inheriting PageData. For each of the classes found a page type is created. For all public properties on the class, a corresponding property on the page type is created.

Creating a page type

Using the Episerver Visual Studio integration, you create a page type by adding the Episerver Page type item to the Pages subfolder under Models in your project. See Get started with Episerver CMS for more information.

To be able to add properties that we want to have for all page types, we added an abstract SitePageData base class, which inherits from EPiServer.Core.PageData. This base class has an SEO property which we want to be used on all pages inheriting from the class.

Example: A simple article page type with a "MainBody" editor area of the property type XhtmlString type, inheriting from the SitePageData base class.

using System;
using System.ComponentModel.DataAnnotations;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.DataAnnotations;
using EPiServer.SpecializedProperties;

namespace MyEpiserverSite.Models.Pages
{
    [ContentType(DisplayName = "ArticlePage", GUID = "b8fe8485-587d-4880-b485-a52430ea55de", Description = "Basic page type for creating articles.")]
    public class ArticlePage : SitePageData
    {
                [CultureSpecific]
                [Display(
                    Name = "Main body",
                    Description = "The main body editor area lets you insert text and images into a page.",
                    GroupName = SystemTabNames.Content,
                    Order = 10)]
                public virtual XhtmlString MainBody { get; set; }
         
    }
}

Example: The SitePage base class, with the SEO property.

namespace MyEpiserverSite.Models.Pages
{
    public abstract class SitePageData : EPiServer.Core.PageData
    {
        [Display(GroupName = "SEO", Order = 200, Name = "Search keywords")]
        public virtual String MetaKeywords { get; set; }
    }
}

When creating a page type using the Episerver Visual Studo extensions, a unique GUID for the page type, will automatically be generated. Also, note that page types implicitly contain a set of built-in properties which will be available for all pages, regardless of the page type instance. See PageData.Property for built-in properties. 

Since the rendering has not yet been created, pages based on this page type cannot be edited from the On-Page edit view, only from the All Properties edit view.

Note: Why are the properties declared as virtual here? What happens in the background is that a proxy class is created for the page type, and data is loaded from the database to a property carrier (Property), receiving the data. Through Castle (Inversion of Control tool), the properties in the proxy page type will be set, and this only works if properties are declared as virtual. If the properties are not declared virtual, you need to implement get/set so that these will read/write data to the underlying property collection instead.

Page controllers and views

Models, controllers and views in MVC, provide a clear separation of data, business logic and presentation. The controller contains the business logic, handles URL requests and selects the view, which is a visual presentation of the data model. In MVC, the controller is the class that is registered to support specific page types, and can be regarded as the template. The template defines which content types it can render in a specific context.

Creating a controller and a view

Using the Episerver Visual Studio integration, you create a controller by adding a new Episerver item of type Page Controller (MVC) to the Controllers folder in your project. Your controller should inherit 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 add the corresponding view for the controller, create a subfolder under Views and add an Episerver item of type Page View (MVC). Or, click inside the controller to add the view. Ensure that you follow the naming conventions in MVC for your model, controllers and views.

To allow for reuse of logic that we want multiple pages to use, we have implemented a page controller base class, which in this case holds logic for a logout action, and inherits from PageController. You can also add a view model, to be able to add more than just page objects to the views. For simpler examples, we have not used a view model here.

To render properties you can use HTML helpers in MVC, for example Html.PropertyFor, which will render property values based on their property type. HTML helpers are described more below.

Example: The controller for displaying the Article page type, inheriting from PageControllerBase.
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using EPiServer;
using EPiServer.Core;
using EPiServer.Framework.DataAnnotations;
using EPiServer.Web.Mvc;
using MyEpiserverSite.Models.Pages;
using System.Web.Security;

namespace MyEpiserverSite.Controllers
{
    [TemplateDescriptor(Default = true)]
    
    public class ArticlePageController : PageControllerBase<ArticlePage>
    {

        public ActionResult Index(ArticlePage currentPage)
        {
            // Implementation of action view the page. 

            return View(currentPage);
        }
    }
}
Example: The page controller base, inheriting from PageController, and with SitePageData as generic type.
namespace MyEpiserverSite.Controllers
{
    public abstract class PageControllerBase<T> : PageController<T> where T : SitePageData
    {
        
        // Providing a logout action for the page.
        public ActionResult Logout()
        {
            FormsAuthentication.SignOut();
            return RedirectToAction("Index");
        }


    }
}

Example: The corresponding rendering view for displaying the Article page. 

@using EPiServer.Core
@using EPiServer.Web.Mvc.Html

@model MyEpiserverSite.Models.Pages.ArticlePage

    <h1>
            @Html.DisplayFor(m => m.Heading)
</h1>

    <h3>
        @Html.PropertyFor(m => m.Introduction)
    </h3>

    <div>
        @Html.PropertyFor(m => m.MainBody)
    </div>

With the added rendering, the property will now also be editable in the On-Page editing view.

Using HTML Helpers

There are also other Episerver HTML helpers that can be used for rendering. There are helpers for rendering links, content areas, translations, and navigation. These helpers are called through Html.DisplayFor, but you can also use them directly.

Using templates

Templates define how content will be rendered. The template (controller) selected to render a content instance, will depend on the specific context. Use the TemplateDescriptor attribute to add metadata and define default templates, and Tags to define which template to use. Based on this information, and any defined display channels and display options settings, the TemplateResolver will decide which template to use in a specific context.

Template registration and routing

Page types and controllers created from code using the Episerver Visual Studio integration, will be strongly typed and inheriting from Episerver base classes. This ensures that the templates used will automatically be registered as supported for the specified page type. See Rendering for more information.

Related topics

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

Last updated: Apr 15, 2016

Recommended reading