# ASP.NET Core Template Overview

The Telerik UI Template TagHelper and HtmlHelper for ASP.NET Core is an integration component that can be used to customize the default appearance of the other Telerik UI for ASP.NET Core components.

The Template allows you to incorporate multiple helper components into the templating options of components like [Data Grid](https://www.telerik.com/aspnet-core-ui/documentation/html-helpers/data-management/grid/overview), [ListView](https://www.telerik.com/aspnet-core-ui/documentation/html-helpers/data-management/listview/overview), [TreeList](https://www.telerik.com/aspnet-core-ui/documentation/html-helpers/data-management/treelist/overview), and others that often require complex layout templates. The created templates are [CSP-compatible](https://www.telerik.com/aspnet-core-ui/documentation/html-helpers/helper-basics/content-security-policy). Also, each component that is defined within the Template configuration will have all the functionalities and options available in the stand-alone nested component.

* [Demo page for the Template HtmlHelper](https://demos.telerik.com/aspnet-core/template/index)

* [Demo page for the Template TagHelper](https://demos.telerik.com/aspnet-core/template/index)

## Basic Configuration

The Template HtmlHelper provides the following configuration options:

* `AddComponent()` specifies the declaration of the Telerik UI helper that will be integrated into the specified component.
* `AddHtml()` adds `HTML` code to the template. It accepts a `string` and `delegate` parameter arguments.

> The delegate overload can only be used with conventional HTML tags and  the ASP.NET Core framework's common [HtmlHelpers](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.rendering.htmlhelperinputextensions?view=aspnetcore-8.0) or [TagHelpers](https://learn.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/built-in/?view=aspnetcore-8.0) . To declare Telerik components, use the `AddComponent()` configuration.

When using the TagHelper mode of the Template component, you can insert the component declaration and any `HTML` code within the `<{parentTagName}-{templateOption}>` tag.

Since the Template is an integration component and cannot be used independently, the following example demonstrates a basic configuration of the Template inside a Grid column template option.

```Razor HtmlHelper
    @(Html.Kendo().Grid<OrderViewModel>()
        .Name("grid")
        .Columns(columns =>
        {
            columns.Bound(c => c.OrderID);
            columns.Bound(p => p.ShipName)
            .ClientTemplate(Html.Kendo().Template()
                .AddHtml("<div class='ship-details'>")
                .AddComponent(btn => btn
                    .Button()
                    .Name("details_${data.OrderID}")
                    .Content("Details")
                    .ThemeColor(ThemeColor.Primary)
                )
                .AddHtml("</div")
            );
        })
        // Other configuration
    )
```

```Razor TagHelper
    @addTagHelper *, Kendo.Mvc

    <kendo-grid name="grid">
        <columns>
            <column field="OrderID"/>
            <column field="ShipName">
                <column-template>
                    <div class="ship-details">
                        <kendo-button name="details_${data.OrderID}" theme-color="ThemeColor.Primary">
                            Details
                        </kendo-button>
                    </div>
                </column-template>
            </column>
        </columns>
        
    </kendo-grid>
```

## Components Integration

You can use the Template component to incorporate any Telerik UI for ASP.NET Core component into the templating options of the following components:

| Component                                                                                                         |
| :---------------------------------------------------------------------------------------------------------------- |
| [Grid](https://www.telerik.com/aspnet-core-ui/documentation/html-helpers/data-management/grid/overview)           |
| [ListView](https://www.telerik.com/aspnet-core-ui/documentation/html-helpers/data-management/listview/overview)   |
| [TaskBoard](https://www.telerik.com/aspnet-core-ui/documentation/html-helpers/data-management/taskboard/overview) |
| [TreeList](https://www.telerik.com/aspnet-core-ui/documentation/html-helpers/data-management/treelist/overview)   |
| [Notification](https://www.telerik.com/aspnet-core-ui/documentation/html-helpers/layout/notification/overview)    |
| [Popover](https://www.telerik.com/aspnet-core-ui/documentation/html-helpers/layout/popover/overview)              |
| [TileLayout](https://www.telerik.com/aspnet-core-ui/documentation/html-helpers/layout/tilelayout/overview)        |
| [Tooltip](https://www.telerik.com/aspnet-core-ui/documentation/html-helpers/layout/tooltip/overview)              |
| [Timeline](https://www.telerik.com/aspnet-core-ui/documentation/html-helpers/navigation/timeline/overview)        |
| [Gantt](https://www.telerik.com/aspnet-core-ui/documentation/html-helpers/scheduling/gantt/overview)              |
| [Scheduler](https://www.telerik.com/aspnet-core-ui/documentation/html-helpers/scheduling/scheduler/overview)      |

For runnable examples, refer to the demos:

* [Integration with Grid](https://demos.telerik.com/aspnet-core/template/integration-grid)
* [Integration with ListView](https://demos.telerik.com/aspnet-core/template/)
* [Integration with TileLayout](https://demos.telerik.com/aspnet-core/template/integration-tilelayout)
* [Integration with Scheduler](https://demos.telerik.com/aspnet-core/template/integration-scheduler)

The components that support editing provide options for custom editors and editing templates. By using the Template component, you can include the desired editors and specify the editor template name through the `EditorTemplateName()` method.

The examples below show how to use the Template component to create custom editors for Inline and Popup editable Grids.

* Inline editable Grid

  ```Razor HtmlHelper
      @(Html.Kendo().Grid<OrderViewModel>()
          .Name("grid")
          .Columns(columns =>
          {
              columns.Bound(p => p.ShipName).EditorTemplateComponentName("ShipNameEditor");
              columns.Command(command => { command.Edit(); command.Destroy(); }).Width(200);
          })
          .ToolBar(tool => tool.Create())
          .Editable(editable => editable.Mode(GridEditMode.InLine))
          // Other configuration
      )
  ```

  ```Razor ShipNameEditor.cshtml
      //~/Views/Shared/EditorTemplates/ShipNameEditor.cshtml
      @model object 

      @Html.Kendo().Template().AddComponent(x => x.TextAreaFor(model => model).Rows(3))

  ```

  ```Razor TagHelper
      @addTagHelper *, Kendo.Mvc

      <kendo-grid name="grid">
          <columns>
              <column field="ShipName">
                  <column-editor-template>
                      <kendo-textarea name="ShipName" rows="3">
                      </kendo-textarea>
                  </column-editor-template>
              </column>
              <column width="200">
                  <commands>
                      <column-command text="Edit" name="edit"></column-command>
                      <column-command text="Delete" name="destroy"></column-command>
                  </commands>
              </column>
          </columns>
          <toolbar>
              <toolbar-button name="create"></toolbar-button> 
          </toolbar>
          <editable mode="inline"/>
          
      </kendo-grid>
  ```

* Popup editable Grid

  ```Razor HtmlHelper
      @(Html.Kendo().Grid<OrderViewModel>()
          .Name("grid")
          .Columns(columns =>
          {
              columns.Bound(p => p.ShipName);
              columns.Bound(p => p.Freight);
              columns.Command(command => { command.Edit(); command.Destroy(); }).Width(200);
          })
          .ToolBar(tool => tool.Create())
          .Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateComponentName("CustomGridEditor"))
          // Other configuration
      )
  ```

  ```Razor CustomGridEditor.cshtml
      //~/Views/Shared/EditorTemplates/CustomGridEditor.cshtml

      @model OrderViewModel

      @(Html.Kendo().Template()
          .AddHtml("<div class=\"k-edit-field\">")
          .AddComponent(tbox => tbox
              .TextAreaFor(model => model.ShipName)
              .Rows(3)
              .Label(l => l.Content("Ship name: "))
          )
          .AddHtml("</div>")
          .AddHtml("<div class=\"k-edit-field\">")
          .AddComponent(tbox => tbox
              .NumericTextBoxFor(model => model.Freight).Min(0).Max(100)
          )
          .AddHtml("</div>")
      )
  ```

  ```Razor TagHelper
      @addTagHelper *, Kendo.Mvc

      <kendo-grid name="grid">
          <columns>
              <column field="ShipName"></column>
              <column field="Freight"></column>
              <column width="200">
                  <commands>
                      <column-command text="Edit" name="edit"></column-command>
                      <column-command text="Delete" name="destroy"></column-command>
                  </commands>
              </column>
          </columns>
          <toolbar>
              <toolbar-button name="create"></toolbar-button> 
          </toolbar>
          <editable mode="popup">
              <editable-template>
                  <kendo-textarea name="ShipName" rows="3">
                  </kendo-textarea>
                  <br/><br/>
                  <kendo-numerictextbox name="Freight" min="0" max="100">
                  </kendo-numerictextbox>
              </editable-template>
          </editable>
          
      </kendo-grid>
  ```

The following example demonstrates how to create a Content Security Policy (CSP)-compatible template with a conditional statement in a Grid column.

```Razor HtmlHelper
    @(Html.Kendo().Grid<OrderViewModel>()
        .Name("grid")
        .Columns(columns =>
        {
            columns.Bound(p => p.IsActive).ClientTemplateHandler("handler");
        })
        // Other configuration
    )
```

```Razor TagHelper
    <kendo-grid name="grid" height="500">
        <columns>
            <column field="IsActive" template-handler="handler" />
        </columns>
        
    </kendo-grid>
```

```JS scripts.js
    function handler(data) {
        if (data.IsActive) {
            return '<div><b>Active order</b></div>'
        } else {
            return `<div>${data.ShipName} is already shipped</div>`;
        }
    }
```

## Converting Existing Templates to CSP-Compatible Templates

With the help of the Template, you can convert the existing components templates ([inline](https://www.telerik.com/aspnet-core-ui/documentation/html-helpers/helper-basics/using-client-templates#inline-client-templates), [external](https://www.telerik.com/aspnet-core-ui/documentation/html-helpers/helper-basics/using-client-templates#external-client-templates), and [partial](https://www.telerik.com/aspnet-core-ui/documentation/html-helpers/helper-basics/using-client-templates#partial-client-templates)) into CSP-compatible ones.

The following snippet demonstrates defining a template for a Grid column by using an inline client template.

```Razor HtmlHelper
    @(Html.Kendo().Grid<OrderViewModel>()
        .Name("grid")
        .Columns(columns =>
        {
            columns.Bound(p => p.ShipName).ClientTemplate("<span style='color:red;'><strong>#=ShipName#</strong></span>");
        })
        // Other configuration
    )
```

```Razor TagHelper
    @addTagHelper *, Kendo.Mvc

    <kendo-grid name="grid">
        <columns>
            <column field="ShipName" template="<span style='color:red;'><strong>#=ShipName#</strong></span>">
            </column>
        </columns>
        
    </kendo-grid>
```

The next snippet shows the new approach for defining a CSP Grid column template through the Template component with a delegate overload.

```Razor HtmlHelper
    @(Html.Kendo().Grid<OrderViewModel>()
        .Name("grid")
        .Columns(columns =>
        {
            columns.Bound(p => p.ShipName).ClientTemplate(Html.Kendo()
                    .Template()
                    .AddHtml(@<text>
                        <span style='color:red;'>
                            <strong>${data.ShipName}</strong>
                        </span>
                    </text>)
            );
        })
        // Other configuration
    )
```

```Razor TagHelper
    @addTagHelper *, Kendo.Mvc

    <kendo-grid name="grid">
        <columns>
            <column field="ShipName">
                <column-template>
                    <span style="color:red;">
                        <strong>${data.ShipName}</strong>
                    </span>
                </column-template>
            </column>
        </columns>
        
    </kendo-grid>
```

The examples that follow illustrate another scenario—converting the [TaskBoard](https://www.telerik.com/aspnet-core-ui/documentation/html-helpers/data-management/taskboard/overview) templates into CSP-compatible templates.

The following snippet demonstrates the previously used approach for defining the templates in the specific scenario.

```Razor HtmlHelper
    @(Html.Kendo().TaskBoard<CardViewModel, Resource>()
        .Name("taskBoard")
        .TemplateId("card-template")
        .Editable(editable => editable
            .HeaderTemplate("<span style='color: green;'>Custom Task editor template</span>")
        )
        //Other configuration
    )
```

```Razor TagHelper
    @addTagHelper *, Kendo.Mvc

    <kendo-taskboard name="taskBoard" template-id="card-template">
        <editable>
            <editable-header-template>
                <span style='color: green;'>Custom Task editor template</span>
            </editable-header-template>
        </editable>
        
    </kendo-taskboard>
```

```JS card-template
    <script id="card-template" type="text/x-kendo-template">
        <div class="template-container">
            <div class="template-header" id="#= ID #" >
                <span class="template-title">#: Title #</span>
                <span class="template-menu">#=cardMenuButton#</span>
            </div>
            <p>#=Description#</p>
            <p>#:kendo.toString(new Date(Start + "Z"), "MMMM dd")#  -  #:kendo.toString(new Date(End + "Z"), "MMMM dd")#</p>
         </div>
    </script>
```

The next snippet shows how to replace the inline client TaskBoard templating options with CSP-compatible templates.

```Razor HtmlHelper
    @(Html.Kendo().TaskBoard<CardViewModel, Resource>()
        .Name("taskBoard")
        .Template(Html.Kendo().Template()
            .AddHtml(@<text>
                <div class="template-container">
                    <div class="template-header" id='${data.ID}'>
                        <span class="template-title">${data.Title}</span>
                        <span class="template-menu">
                            ${data.cardMenuButton}
                        </span>
                    </div>
                <p>${data.Description}</p>
                <p>
                    ${kendo.toString( new Date(data.Start + "Z"), "MMMM dd")}  -  ${kendo.toString(new Date(data.End +  "Z") , "MMMM dd")}
                </p>
                </div>
            </text>)
         )
        .Editable(editable => editable
            .HeaderTemplate(Html.Kendo().Template()
                .AddHtml("<span style='color: green;'>Custom Task editor template</span>")
            )
        )
        // Other configuration
    )
```

```Razor TagHelper
    @addTagHelper *, Kendo.Mvc

    <kendo-taskboard name="taskBoard">
        <taskboard-template>
            <div class="template-container">
                <div class="template-header" id="${data.ID}" >
                    <span class="template-title">${data.Title}</span>
                    <span class="template-menu">${data.cardMenuButton}</span>
                </div>
                <p>${data.Description}</p>
                <p>${kendo.toString( new Date(data.Start + "Z"), "MMMM dd")}  -  ${kendo.toString(new Date(data.End + "Z") , "MMMM dd")}</p>
            </div>
        </taskboard-template>
        <editable>
            <editable-header-template>
                <span style='color: green;'>Custom Task editor template</span>
            </editable-header-template>
        </editable>
        
    </kendo-taskboard>
```

## See Also

* [Basic Usage of the Template (Demo)](https://demos.telerik.com/aspnet-core/template/index)
* [Content Security Policy](https://www.telerik.com/aspnet-core-ui/documentation/html-helpers/helper-basics/content-security-policy)
* [Knowledge Base Section](https://www.telerik.com/aspnet-core-ui/documentation/knowledge-base)
* [Server-Side API](https://www.telerik.com/aspnet-core-ui/documentation/api/template)
