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

`TemplateDescriptor` lets you add meta data when registering templates for content types, and tags can be used, for example, to control the rendering of objects in a content area.


The examples here are based on MVC.

## TemplateDescriptor attribute

A page or a block can have multiple associated templates, for example, one for a web channel and one for a mobile device. Pages can also have a _partial template_ used, for example, when the page is displayed inside the content area of another page. 

`TemplateDescriptor` is an optional attribute that you can use to register templates, and is involved when the system decides which template to use when rendering a content instance in a specific context. See [Rendering](🔗)  and  [Selecting templates](🔗) for information on how templates are registered and selected. Use the attribute to add metadata such as template path, inheritance, content type model, and description. You can also define a default template to be used for all content types.  

### Properties

The attribute is found in the `EPiServer.Framework.DataAnnotations` namespace, and some of its properties are described below.

  • `Path` – Default: null – The path to the rendering template; only needs to be set if the folder structure **does not** follow the namespace structure. A namespace convention searches for the file in the path according to the namespace.

  • `ModelType` – Default: null – The model for the content type. This can be set for **untyped** templates which derives from `EPiServer.TemplatePage` to set the model type, which is the type of the `CurrentPage` property.

  • `Default` – Default: false – Defines the template as the default template for the model type.

  • `Description` – Default: null – Contains a description of the template.

  • `Inherited` – Default: false – When set to **true**, model types that inherit from the **ModelType** get the template as a supported template.

### Behavior

  • If `TemplateDescriptor` is **not present**, template inheritance will be **true** by default.

  • If `TemplateDescriptor` is **present but without specified parameters**, the default values specified above will apply.

  • If `TemplateDescriptor` is **present with inherited set to true**, the template will be inherited by all page types based on the associated page type. This is useful if you need a fallback template for content types without specific templates. 

### Examples

#### Default template

The template (controller) for an `Article` page type, with the `TemplateDescriptor` attribute present. `Inherited=false`, meaning that this template will be used as the default template for the `ArticlePage` page type, and no inheritance will take place.

#### Partial page rendering

The following example shows how to use `TemplateDescriptor` for defining a partial page renderer to be used when rendering a page inside a content area.

Assume we have the following `SitePageData` base class with a summary (`MetaKeywords` string) and an image:

We have a **partial page controller** decorated with `TemplateDescriptor` with `Inherited=true`, to render page partials for pages inheriting from `SitePageData`. The controller selects a view located in a folder specified by the namespace convention.

The **partial view** has an if-else construct checking if the model has a template for the content. Any page inheriting from our `SitePageData`, will now be rendered displaying the page name with a link, the `MetaKeywords` string, and an image, when added to the content area of another page.

#### Pages without controllers

An example of how you can handles page types that do not have their own specific controllers by specifyinenherited=true\`, and dynamically selecting template. See the [Optimizely CMS (Alloy) sample site](🔗) for a fully working sample.

## Use tags

You can apply _tags_ to be used in the rendering selection. When a template is associated with a tag, then that template is used only when the calling context, such as `Property` or `PropertyFor` in a view, has a matching tag. You can also have different content areas render the same content in different ways using tags. If you have active [display channels](🔗) for your content types, the `ChannelName` will act as a tag in the rendering selection. 

### Examples

#### Register multiple templates

Assume you have a model containing a teaser block with a heading and an image as follows.

  • Register two templates for the teaser block to display it differently depending on the context.

  • Add two sidebar templates (left and right) for displaying the block in the sidebar area of web pages that have this.

  • Add register a template for the standard block, which is part of our content model. The blocks are displayed in a content area of the start page for our website.

For performance reasons, you should use _partial views directly_ for block types, and not controllers. See [Block types and templates](🔗). Because you have partial views without controllers here, use `EPiServer.Web.Mvc.IViewTemplateModelRegistrator` to register your templates. In the Business folder of your project, create a `ViewTemplateModelRegistrator` class inheriting from `IViewTemplateModelRegistrator`, and add the desired templates and tags.

The following code shows the template registration class using `IViewTemplateModelRegistrator`:

The following code shows the _SidebarTeaserBlockRight_ partial view for the teaser block (there is an identical _SidebarTeaserBlockLeft_ for the left one):

 The following code shows the rendering view for the start page, where the blocks are displayed:

How tagging is used in template selection:

  • If the `AvailableWithoutTag` attribute for a template is set to **true**, the template is applied regardless of whether the rendering context has a corresponding tag or not.

  • If the `AvailableWithoutTag` is set to **false**, or does not exist, the template is not applied unless the rendering context has a corresponding tag_._

In this scenario, the following happens:

  • The start page _GeneralContentArea_ has the _RenderingTags.Sidebar_ tag, which means that only templates with this tag are applied, and without the AvailableWithoutTag or where this set to _false_

  • The _SidebarTeaserLeft_ template has a matching tag and `AvailableWithoutTag` set, and is applied. This is also valid for the template used for the Standard block.

  • The _SidebarTeaserRight_ template has a matching tag, and `AvailableWithoutTag = true`. This template is applied, even if the _RenderingTags.Sidebar_ tag would be removed from the content area.