In ABP Framework, `text template` is a mixture of text blocks and control logic that can generate a `string` result. An open source package [Scriban](https://github.com/lunet-io/scriban) is used for the control logic and [Abp.Localization](Localization.md) is used to make content easily localizable. The generated string can be text of any kind, such as a web page, an e-mail content etc.
Template Definition is an object that contains some information about your `Text Templates`. Template Definition object contains the following properties.
-`Name`*(string)*
-`IsLayout`*(boolean)*
-`Layout`*(string)* contains the <u>name of layout template</u>
Inline localized Text Templates is using only one content resource, and it is using the [Abp.Localization](Localization.md) to get content in different languages/cultures.
First of all, create a class that inherited from `TemplateDefinitionProvider` abstract class and create `Define` method that derived from the base class.
`Define` method requires a context that is `ITemplateDefinitionContext`. This `context` is a storage for template definitions and we will add our template definitions to the context.
> **NOTE!** For default, ABP uses **Virtual File System** for text templates. Do not forget to register your files as an `Embedded Resource`. Please check the [Virtual File System Documentation](Virtual-File-System.md) for more details.
> All given examples are for `Virtual File Text Template Definitions`.
As you see in the given example, all Text Templates are added with `(ITemplateDefinitionContext)context.Add` method. This method requires a `TemplateDefinition` object. Then we call `WithVirtualFilePath` method with chaining for the describe where is the virtual files.
`WithVirtualFilePath` is requires one `tpl` file path for the `Inline Localized` Text Templates. If your Text Tempalte is `Multi Localized` you should create a folder and store each different culture files under that. So you can send the folder path as a parameter to `WithVirtualFilePath`.
> Inline Localized File
```
/ Folder / ForgotPasswordEmail.tpl
```
> Multi Content Localization
```
/ Folder / ForgotPasswordEmail / en.tpl
/ Folder / ForgotPasswordEmail / tr.tpl
```
## Rendering
When one template is registered, it is easy to render and get the result with `ITemplateRenderer` service.
`ITemplateRenderer` service has one method that named `RenderAsync` and to render your content and it is requires some parametres.
`model` is a dynamic object. This is using to put dynamic data into template. For more information, please look at [Scriban Documentation](https://github.com/lunet-io/scriban).
> Example: If you try to render content with _"es-MX"_ it will search your template with _"es-MX"_ culture, when it fails to find, it will try to render _"es"_ culture content. If still can't find it will render the default culture content that you defined.
When you want to get your stored template content you can use `ITemplateContentProvider`.
`ITemplateContentProvider` has one method that named `GetContentOrNullAsync` with two different overriding, and it returns you a string of template content or null. (**without rendering**)
-`templateName` (_string_) or `templateDefinition` (_`TemplateDefinition`_)
-`cultureName` (_string_)
-`tryDefaults` (_bool_)
-`useCurrentCultureIfCultureNameIsNull` (_bool_)
### Usage
First parametres of `GetContentOrNullAsync` (`templateName` or `templateDefinition`) are required, the other three parametres can be null.
If you want to get exact culture content, set `tryDefaults` and `useCurrentCultureIfCultureNameIsNull` as a `false`. Because the `GetContentOrNullAsync` tries to return content of template.
> Example Scenario
> If you have a template content that culture "`es`", when you try to get template content with "`es-MX`" it will try to return first "`es-MX`", if it fails it will return "`es`" content. If you set `tryDefaults` and `useCurrentCultureIfCultureNameIsNull` as `false` it will return `null`.
`Get` and `GetOrNull` requires a string parameter that name of template definition. `Get` will throw error when it is not exist but `GetOrNull` returns `null`.
`ITemplateContentContributor` has a one method that named `GetOrNullAsync`. This method must return content **without rendering** if that is exist in your resource or must return `null`.