---
title: Developing page templates in MVC
related:
  - https://docs.kentico.com/k12sp/developing-websites/page-builder-development.md
  - https://docs.kentico.com/k12sp/developing-websites/page-builder-development/developing-page-templates-in-mvc/filtering-page-templates-in-mvc.md
  - https://docs.kentico.com/k12sp/managing-website-content/using-page-templates-in-mvc.md
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

Page templates allow content editors to gain greater control over the layout of pages, without the need to ask a developer to modify the code in the MVC project.

Templates make it easy to choose and switch between page layouts, so they are suitable for creating pages with a predesigned or repeating structure, such as landing pages. Developers define the layout of these pages by preparing page templates in the code and content editors then create new landing pages based on these templates. 

Content editors can also utilize page templates for creating pages with structured content (even without any page builder editable areas). This can be useful, for example if you have multiple possible layouts for product or article pages, and wish to allow editors to choose a suitable layout for each individual page.

When    [creating a page](https://docs.kentico.com/k12sp/managing-website-content/working-with-pages/creating-new-pages-in-mvc.md) , content editor can choose from two types of page templates:

- **Default templates** are defined in the code of the MVC project. They specify the layout of a page, and the content can be then supplied by a content editor.
- **Custom templates** are based on default templates. On top of the layout defined in the original default template, custom templates also contain a snapshot of [page builder content](https://docs.kentico.com/k12sp/managing-website-content/using-widgets-in-mvc.md), such as widgets and sections, taken from an existing page. Structured data stored in the fields of pages is not included within custom templates. See how to [create custom page templates](https://docs.kentico.com/k12sp/managing-website-content/using-page-templates-in-mvc.md#saving-pages-as-custom-page-templates).

> **Note:** **Page template filtering**
>
> When you register page templates in your solution, you need to implement page template filtering to limit page templates only for specific page types. Otherwise, an error occurs when creating pages of any page type with the _Page builder_ feature enabled, but no available page template.

## Creating pages that support page templates

To be able to utilize the benefits of page templates on your pages, you first need to create and configure content-only page types and adjust the controllers that handle displaying of the given pages.

- Start by preparing a content-only page type for your template-based pages:

  1. In the **Page types** application, [create a content-only page type.](https://docs.kentico.com/k12sp/developing-websites/defining-website-content-structure/creating-and-configuring-page-types/creating-content-only-page-types.md)
  2. Edit () the created page type, and perform the following on the  **General**  tab:
     1. [Specify the URL pattern](https://docs.kentico.com/k12sp/developing-websites/defining-website-content-structure/creating-and-configuring-page-types/configuring-page-types/specifying-the-url-pattern-for-content-only-pages.md) for the page type.
     2. Enable the _Use Page tab_ setting.
     3. Click **Save**.
- In your MVC site's code, create a controller with a GET action that handles rendering of the pages:
  - The GET action must return a **TemplateResult** object.
  - You need to set the _pageI&#x64;_&#x70;arameter of the _TemplateResult_ constructor to the ID identifier of the rendered page. You can get the ID value via the _DocumentID_ property of the _TreeNode_ object that represents the page.

    ```csharp title="Example"

            /// <summary>
            /// A GET action displaying the page where you wish to use page templates.
            /// </summary>
            /// <param name="pageAlias">Page alias of the displayed page.</param>
            public ActionResult Index(string pageAlias)
            {
                // Retrieves the page from the Kentico database
                TreeNode page = DocumentHelper.GetDocuments()
                    .Path("/Landing-pages", PathTypeEnum.Children)
                    .WhereEquals("NodeAlias", pageAlias)
                    .OnCurrentSite()
                    .TopN(1)
                    .FirstOrDefault();

                // Returns a 404 error when the retrieving is unsuccessful
                if (page == null)
                {
                    return HttpNotFound();
                }

                // Returns a TemplateResult object, created with an identifier of the page as its parameter
                // Automatically initializes the page builder feature for any editable areas placed within templates
                return new TemplateResult(page.DocumentID);
            }


    ```

    > **Info:** **Notes**
    >
    > - When developing pages that use page templates, you do NOT need to create a view for the page itself. Instead, the output of the page is based on the view of the selected template.
    > - Returning the _TemplateResult_ object automatically performs the API initialization of the [page builder](https://docs.kentico.com/k12sp/developing-websites/page-builder-development.md) feature for any editable areas placed within the templates.

When [creating new pages](https://docs.kentico.com/k12sp/managing-website-content/working-with-pages/creating-new-pages-in-mvc.md) of the given type in the **Pages** application, content editors can now select a page template. [Registered page templates](#registering-page-templates) are automatically available for selection, depending on predefined [page template filters](https://docs.kentico.com/k12sp/developing-websites/page-builder-development/developing-page-templates-in-mvc/filtering-page-templates-in-mvc.md). If only one template is available for a given page, it is selected automatically.

The following steps describe how Kentico MVC applications handle requests for pages that use a page template:

1. The request goes through the standard routing process and is handled by a specific controller action (needs to be implemented).
2. The action returns a _TemplateResult_, initialized with the ID of the given Kentico page.
3. Based on the ID, the system gets the template (along with any configured [properties](https://docs.kentico.com/k12sp/developing-websites/page-builder-development/developing-page-templates-in-mvc/defining-page-template-properties-in-mvc.md)) and page builder content for the specified page.
4. The template's controller (either default or custom) returns and displays the page content based on the template's view (see [Implementing page templates](#implementing-page-templates) below for details).

## Implementing page templates

On a basic technical level, page templates are HTML pages. The main step in the development of a page template is to create a full page **view** that defines the output.

Within the MVC architecture, the page template view is served by a controller and a model is used to pass any required data. In many cases, templates can utilize a default controller and view model provided by the Kentico API. See the following scenarios for more information:

- [Basic page templates](#basic-page-templates)
- [Page templates with a custom controller](#page-templates-with-a-custom-controller)

In both cases you can develop page templates with properties, which allow content editors to customize the template appearance in the Kentico administration interface. For templates with configurable properties, you need to create an additional model class that represents the properties and passes their values to the controller. See [Defining page template properties](https://docs.kentico.com/k12sp/developing-websites/page-builder-development/developing-page-templates-in-mvc/defining-page-template-properties-in-mvc.md) to learn more.

> **Note:** **MVC Areas**
>
> Page templates are designed to be used in the global scope and their code files must be placed in the application root of your MVC project (not in an MVC Area). Creating page templates in MVC Areas may lead to unexpected behavior.

### Basic page templates

Use the following process to develop a page template:

1. Create a view with code that defines the output of the page template according to the general [MVC best practices](https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/introduction/).
   - The output must be a full HTML page, so the view must include the following:

     - Full HTML markup, including the _html, head_ and _body_ elements
     - Links to all necessary resources, such as stylesheets and scripts
     - Links to [page builder scripts and styles](https://docs.kentico.com/k12sp/developing-websites/page-builder-development/creating-pages-with-editable-areas-in-mvc.md#loading-page-builder-scripts-and-styles)
   - Use MVC layouts with the template view for any shared output code (based on your requirements, you can use your site's main layout, a dedicated layout for page templates, etc.).
   - We recommend storing page template views in the _\~/Views/Shared/PageTemplates_ folder, and using a view name that matches the **identifier** assigned to the template [upon its registration](#registering-page-templates) prefixed with the underscore (_'\_'_) character. Alternatively, you can use any required view location or name, and then specify it when registering the template.

> **Tip:** **Accessing the template's page**
>
> If you need to work with the data of the page using the currently processed page template, use the **ComponentViewModel** class as the view's model and access its **Page** property. The property returns a _TreeNode_ object representing the given page. If you need to load values from the fields of a specific page type, you can convert the _TreeNode_ object to an instance of a specific [page type wrapper class](https://docs.kentico.com/k12sp/developing-websites/generating-classes-for-kentico-objects.md) (the page using the template must then be of the given page type).

2. Register the page template into the system. See [Registering page templates](#registering-page-templates).

With this approach, the template's view is automatically displayed using a default controller provided by the Kentico API. The values of any [properties](https://docs.kentico.com/k12sp/developing-websites/page-builder-development/developing-page-templates-in-mvc/defining-page-template-properties-in-mvc.md) defined for the template can be passed to the view by using the default _ComponentViewModel_ class as the model.

> **Info:** **Example of page template development**
>
> To see a scenario with full code samples which will guide you through the process of developing a simple template, visit [Example - Developing a page template with a configurable property](https://docs.kentico.com/k12sp/developing-websites/page-builder-development/developing-page-templates-in-mvc/defining-page-template-properties-in-mvc.md#example---developing-a-page-template-with-a-configurable-property).

### Page templates with a custom controller

When developing page templates with advanced functionality, you may need to take full control over the template's logic. You can do this by implementing the template's controller and view model, in addition to the view. This allows you to run any custom code within the template's controller, pass any type of required data to the view, or even switch between completely different views based on the current scenario.

The following steps describe the advanced development process for page templates:

1. Create a controller class for the page template.
   - We recommend storing template controllers in the _\~/Controllers/PageTemplates_ folder.

2. Make the controller inherit from the **PageTemplateController** base class (available in the _Kentico.PageBuilder.Web.Mvc.PageTemplates_ namespace).

3. Implement the default **Index** action in the controller, which is used to retrieve the template markup. The action must return the page template's HTML content, typically a view.

   > **Tip:** **Accessing the template's page**
   >
   > If you need to access fields of the page using the currently processed page template, call the generic **GetPage** method (provided by the _PageTemplateController_ base class). The method takes a [page type wrapper class](https://docs.kentico.com/k12sp/developing-websites/generating-classes-for-kentico-objects.md) as the PageType parameter and returns a page object of the specified page type. Alternatively, you can call the **GetPage** method returning only a _TreeNode_ object representing the given page.
   >
   > ```csharp
   >
   > // Gets the page of the Article page type containing the currently processed page template
   > var article = GetPage<Article>();
   >
   > ```

   > **Note:** **Notes**
   >
   > - Do not disable POST requests for the Index action (e.g., by using the HttpGet attribute). POST requests to the Index action are used in the page builder feature.
   > - Template controller actions used to retrieve the markup cannot be asynchronous (cannot use the async function declaration). Actions that render template markup are called as child actions when rendering the markup of a page, but MVC 5 does not support asynchronous child controller actions.

4. Create any required view model classes used to pass data from the template controller to the view.

   - We recommend storing template models in the _\~/Models/PageTemplates/_ folder.

> **Note:** **Referencing actions of page template controllers**
>
> When using methods that reference page template controller actions within the code of the given view template (e.g. _RedirectToAction_ in the controller or _Html.ActionLink_ in views), you need to explicitly specify the controller name as a parameter of the method. For example, use **RedirectToAction(actionName, controllerName**) instead of _RedirectToAction(actionName)_.

5. Prepare a view that defines the output of the page template according to the general [MVC best practices](https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/introduction/).
   - The output must be a full HTML page, so the view must include the following:

     - Full HTML markup, including the _html, head_ and _body_ elements
     - Links to all necessary resources, such as stylesheets and scripts
     - Links to [page builder scripts and styles](https://docs.kentico.com/k12sp/developing-websites/page-builder-development/creating-pages-with-editable-areas-in-mvc.md#loading-page-builder-scripts-and-styles)
   - Use MVC layouts with the template view for any shared output code (based on your requirements, you can use your site's main layout, a dedicated layout for page templates, etc.).
   - We recommend storing page template views in the _\~/Views/Shared/PageTemplates_ folder.
6. Register the template into the system. See [Registering page templates](#registering-page-templates).

With this advanced development approach, you have full responsibility and control over the template's controller, view model, and view.

## Registering page templates

Every page template needs to be registered into the system to be available. Register templates using the **RegisterPageTemplate** assembly attribute (available in the _Kentico.PageBuilder.Web.Mvc.PageTemplates_ namespace).

To register [basic templates](#basic-page-templates) (without a custom controller class), we recommend adding the assembly attributes to a dedicated code file. For example, you can create a file named **PageBuilderComponentRegister.cs** in your project's _\~/App\_Start_ folder and use it to register your page builder components. For basic page templates, specify the following attribute parameters:

- **Identifier** – the unique identifier of the template. We recommend using a unique prefix in your template identifiers to prevent conflicts when deploying templates to other projects, for example matching your company's name.
- **Name** – the name used to identify the template when displayed in the Kentico administration interface.
- **PropertiesType** – only required for [templates with properties](https://docs.kentico.com/k12sp/developing-websites/page-builder-development/developing-page-templates-in-mvc/defining-page-template-properties-in-mvc.md). Specifies the _System.Type_ of the template's property model class.
- (Optional) **CustomViewName** – specifies the name and location of the view that defines the template's output. If not set, the system searches for a corresponding _\_.cshtml_ view in the _\~/Views/Shared/PageTemplates_ folder.

  ```csharp title="Basic template registration example"

  [assembly: RegisterPageTemplate("CompanyName.MyTemplate", "My template", typeof(CustomTemplateProperties), "PageTemplates/_MyTemplate")]

  ```

For [templates with a custom controller](#page-templates-with-a-custom-controller), you can add the assembly attribute directly into the controller code file (above the controller class). In this case, specify the following attribute parameters:

- **Identifier** – the unique identifier of the template. We recommend using a unique prefix in your template identifiers to prevent conflicts when deploying templates to other projects, for example matching your company's name.
- **ControllerType** – the _System.Type_ of the template's controller class.
- **Name** – the name used to identify the template when displayed in the Kentico administration interface.

  ```csharp title="Controller template registration example"

  [assembly: RegisterPageTemplate("CompanyName.MyTemplate", typeof(MyTemplateController), "My template")]

  ```

When registering any type of page template, you can also set the following optional attribute properties:

- **Description** – the description of the template displayed as a tooltip.
- **IconClass** – the [font icon class](http://devnet.kentico.com/docs/icon-list/index.html) displayed as a thumbnail when selecting templates.

```csharp

[assembly: RegisterPageTemplate("CompanyName.MyTemplate", typeof(MyTemplateController), "My template", Description = "This is a custom template.", IconClass="icon-l-img-3-cols-3")]

```

> **Tip:** **Localizing template metadata**
>
> To allow content editors to experience the page builder in their preferred UI culture, you can [localize](https://docs.kentico.com/k12sp/multilingual-websites/setting-up-a-multilingual-user-interface/localizing-mvc-builder-components.md) the **Name** and **Description** values of page templates.

## Storing files for template-based pages

We recommend storing files for pages that utilize page templates in media libraries. [Media library files](https://docs.kentico.com/k12sp/configuring-kentico/configuring-the-environment-for-content-editors/configuring-media-libraries.md) are not bound to specific pages and their content is reusable (as opposed to [page attachments](https://docs.kentico.com/k12sp/managing-website-content/working-with-files/page-attachments.md)). Custom page templates store only the configuration of pages, e.g. for  [multimedia files](https://docs.kentico.com/k12sp/managing-website-content/working-with-files.md)  only the file identifiers are stored and not the files themselves.  As a result, if you create a custom template from a page that displays a file, new pages created with this template will display the file only if it is stored in a media library.

## Adding scripts and styles for page templates

To add JavaScript and CSS styles required by your page templates, we recommend placing script and stylesheet files into sub-folders under the  _**\~/Content/PageTemplates**_ directory of your MVC project (you may need to create the _PageTemplate&#x73;_&#x64;irectory). You can use sub-folders that match the identifiers of individual templates, or a _Shared_ sub-folder for assets used by multiple templates.

The system does not automatically include or create bundles for _.js_ and _.css_ page template files. You need to include and link all custom scripts and styles for your page templates manually.

> **Note:** **CSS notes**
>
> - Only use the _\~/Content/PageTemplate&#x73;_&#x64;irectory to add **basic styles** that are required for the template to render correctly. Any **site-specific styles** that finalize the live site design of the template should be handled separately within the given site's main stylesheet.
> - To avoid potential conflicts between styles from other third-party components, we recommend adding a unique prefix to your CSS classes and identifiers (for example _#CompanyName-mid-column_), or employ similar measures to ensure their uniqueness.
