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.
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 `
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.
TemplateDescriptor` is **not present**, template inheritance will be **true** by default.
TemplateDescriptor` is **present but without specified parameters**, the default values specified above will apply.
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.
#### 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.
#### 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 `
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.