---
title: Select templates
slug: cms-11/dev-docs/selecting-templates
docTags: 
createdAt: 2026-07-22T19:45:22.664Z
---

The resulting rendering template for a requested content instance is selected based on page or partial renderers, tags, and active display channels.

:::hint{type="info"}
**Note**
The examples are based on MVC.
:::

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 when you display the page inside the content area of another page. See [Render content](docId:1j5tkfTPZbGw5lRhAh4Xx) and [TemplateDescriptor and tags](https://docs.developers.optimizely.com/content-management-system/v11.0.0-cms/docs/templatedescriptor-and-tags).

If you register multiple templates, the `TemplateResolver` service selects the resulting rendering template using an algorithm based on content model, template types, rendering mode (page or partial rendering), tags, and inheritance. If needed, you can use *events* to override the `TemplateResolver` selection.

![the ](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/Jcr7OLtEoW8M2iY4EXxWF-20260722-194641.png "selectingtemplates.png")

A default `TemplateResolver` implementation selects templates based on the procedure below.

1. The `EPiServer.Web.TemplateResolver.TemplateResolving` event is raised. If an event handler selects a template, it uses it without further handling.
2. It filters templates matching the desired content type according to the rendering mode: If it is a *page*, it selects a suitable *controller*; if it is *partial rendering*, it selects a suitable *partial controller* or *partial view*. For partial templates, it filters the list according to the main template.
3. If it requests the template with a specific tag, it filters the list on that tag. If no template matching the tag exists, it considers templates from Step 2.
4. If any **display channel** is active, and template tags match that channel, it filters templates for `DisplayChannel`.
5. From remaining templates, the **shortest inheritance chain** to the `TemplateModel` marked as **Default** and **not inherited,** is selected.
6. If there is no match from Step 5, the **shortest inheritance chain** to `TemplateModel` that is marked as **Default,** is selected.
7. If there is no match from Step 6, the **shortest inheritance chain** to `TemplateModel`, is selected.
8. The `EPiServer.Web.TemplateResolver.TemplateResolved` event is raised, providing a chance to replace the selected template.

:::hint{type="info"}
**Note**
The shortest inheritance chain means that a template that is registered **directly for the content model type** is preferred before a template registered for a base class or interface. For interfaces, the length of the inheritance chain is defined by following the inheritance chain upwards to see where the interface is implemented.
:::

## Examples

The following examples assume you have a content model and use multiple rendering templates for different display channels. See [Content](docId:9aGByn6kCHLuvaqWTBQtR), [Render content](docId\:N9EhLwAoRUYvRy2ef0Rpr), and [Display channels](docId\:DOH7by8bAqGeC4FnaZciq) for information.

### Select page rendering

The template selected to render a content instance depends on the context, such as channel and tagging. To automatically register a template for rendering, it must implement `EPiServer.Web.IRenderTemplate<T>` (where T states which model it can render). If you use a **base class** like `PageController<T>` or `BlockComponent<T>`you do not need to implement the interface explicitly for your templates. In addition, you can use the `TemplateDescriptorAttribute` to specify more details about the template, such as tags and inheritance. See [TemplateDescriptor and tags](https://docs.developers.optimizely.com/content-management-system/v11.0.0-cms/docs/templatedescriptor-and-tags).

**Example:** A content type model.

```csharp
[ContentType]
public class MyPage: PageData {
  public virtual string Heading {
    get;
    set;
  }
  public virtual string MainIntro {
    get;
    set;
  }
  public virtual XhtmlString MainBody {
    get;
    set;
  }
}
```

Given that there are templates defined as follows:

```csharp
public partial class MyPageTemplate : TemplatePage<MyPage> { }

[TemplateDescriptor(Tags = new string[] { RenderingTags.Mobile })]
public partial class MyPageMobileTemplate : TemplatePage<MyPage> { }

[TemplateDescriptor(Inherited = true)]
public partial class MyFallbackTemplate : TemplatePage<PageData> { }

public partial class MyPageTeaser : ContentControllerBase<MyPage> { }

[TemplateDescriptor(Inherited = true)]
public partial class PageTeaser : ContentControllerBase<PageData> { }
```

You register the above templates as templates for **MyPage**. You can register a template for a base type and an interface (`MyFallbackController` and `PageTeaser` in the code sample), which you register for `PageData`, not the specific type). If you want the template to be available for **all** subtypes, for example, if you want to have a **fallback** template for content types without a specific template, set `Inherited=true` for the `TemplateDescriptor` attribute.

For the example above, a browser request for a page of the type *MyPage* will result in the following:

- If **no** `DisplayChannel` is active, the *MyPageTemplate* template is selected because no tag is active (disqualifies `MyPageMobileTemplate`), and `MyPageTemplate` has shorter inheritance chain than `MyFallbackTemplate`. `MyPageTeaser` and `PageTeaser` are partial renderers and are filtered away.
- If a `DisplayChannel` named *Mobile* is active, it selects the *MyPageMobileTemplate* template, because it prefers templates with a tag matching active channels.

### Select block rendering

Blocks can be either a property on a page or a shared block instance in a content area. The selection of a template for a block is similar to the selection of a page template, except that you can only render blocks in the context of a page template. Render blocks using partial views or view components. When rendering a block in a page template, you can use tags to define how you should render the block.

**Example:** Templates defined for a *MyBlock* block type.

```csharp
[ContentType]
public class MyBlock : BlockData {}

[TemplateDescriptor(Default = true)]
public partial class MyBlockTemplate : BlockContoller<MyBlock> {}

[TemplateDescriptor(Tags = new string[] {"Mobile"})]
public partial class MyBlockMobileTemplate : BlockContoller<MyBlock> {}
```

You can also use a **tag** to define rendering in a specific area, such as a *Sidebar* in a page template:

```csharp
@Html.PropertyFor(x=>x.MyBlock, new {tag = "SideBar"})
```

See [TemplateDescriptor and tags](https://docs.developers.optimizely.com/content-management-system/v11.0.0-cms/docs/templatedescriptor-and-tags) for information on how to apply tags.

### Block layout in a content area

If you specify a tag for a content area, then content added to that area will use a template matching that tag. You can use **display options** to let editors define the layout of a block in a content area from edit view. See [Display options](docId\:jDv7USrLU_fcbWkptBl4E).
