HomeDev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideGitHubNuGetDev CommunityDoc feedbackLog In
GitHubNuGetDev CommunityDoc feedback


The examples here are based on MVC.

Pages, page types and page templates are linked together in the following way:

  • _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 find examples of how to work with page types and associated controllers, views and templates for rendering the content.


Standard routing is not registered by default for MVC, but if it is used, renaming of a controller or action will affect the URL/route to the action.

## Page types

In Optimizely Content Management System (CMS), 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.

### Create a page type

Using the [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 [Getting started with Content Cloud (CMS 11)](🔗).

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`, inheriting from the `SitePageData` base class.

When creating a page type using the Episerver Visual Studio extension, a unique GUID for the page type is automatically generated. Also, note that page types implicitly contain a set of _built-in properties_ which are 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.


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.

### Create a controller and a view

Using the Optimizely Visual Studio extension, you create a controller by adding a new CMS 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 CMS item of type _Page View (MVC)_. Or, click inside the controller to add the view. Ensure that you follow the standard _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 renders 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.

**Example:** The page controller base, inheriting from `PageController`, and with `SitePageData` as generic type.

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

With the added rendering using `Html.PropertyFor`, the property is now also editable in the **On-Page** editing view.

## Use HTML Helpers

You can also use other specific CMS HTML helpers as an alternative to `Html.PropertyFor`. There are helpers for rendering links, content areas, translations, and navigation. These HTML helpers are called through `Html.DisplayFor`, but you can also use them directly.

## Use templates

Templates define how content is rendered. The template (controller) selected to render a content instance, depends 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 decides which template to use in a specific context.

### Template registration and routing

Page types and controllers created from code using the CMS Visual Studio integration, are strongly typed and inherit from CMS base classes. This ensures that the templates used are automatically registered as supported for the specified page type. See [Rendering](🔗) for more information.