T4 Template Directive

A Visual Studio T4 text template usually starts with a template directive, which specifies how the template should be processed. There should be no more than one template directive in a text template and any files that it includes.

For a general overview of writing text templates, see Writing a T4 Text Template.

Using the Template Directive

<#@ template [language="VB"] [compilerOptions="options"] [culture="code"] [debug="true"] [hostspecific="true"] [inherits="templateBaseClass"] #>

The template directive has several attributes that allow you to specify different aspects of the transformation. All the attributes are optional.

compilerOptions attribute

These options are applied when the template has been converted into Visual C# or Visual Basic, and the resulting code is compiled.

culture attribute

  • Example:
    culture="de-CH"

  • Valid values:
    "", the invariant culture, which is the default.

    A culture expressed as a string in the form xx-XX. For example, en-US, ja-JP, de-CH, de-DE. For more information, see System.Globalization.CultureInfo.

The culture attribute specifies the culture to use when an expression block is converted to text.

debug attribute

  • Example:

    debug="true"
    
  • Valid values:
    true, false. False is the default.

The debug attribute specifies whether or not debugging is enabled. If it is true, the intermediate code file will contain information that enables the debugger to identify the position in your template where a break or exception occurred. For design-time templates the intermediate code file will be written to your %TEMP% directory.

To launch the debugger at a particular point in the execution of a template, insert a call to Launch. To break execution at subsequent points, insert a call to Break. For example:

<#@ template debug="true" language="C#" #>
<#@ output extension=".txt" #>
Output something.
<# 
 // Break here:
 System.Diagnostics.Debugger.Launch();  
#>
Output more.
<#
 // Break here also:
 System.Diagnostics.Debugger.Break();  
#>
Output more.

For more information, see Walkthrough: Debugging a Text Template.

hostspecific attribute

  • Example:

    hostspecific="true"
    
  • Valid values:
    true, false. False is the default.

If you set the value of this attribute to true, a property named Host is added to the class generated by your text template. The property is a reference to the host of the transformation engine, and is declared as Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost. If you have defined a custom host, you can cast it to the custom host type.

Because the type of this property depends on the type of host, it is only useful if you are writing a text template that works only with a specific host.

When hostspecific is true and you are using Visual Studio, you can cast this.Host to IServiceProvider to access Visual Studio features. You can also use Host.ResolvePath(filename) to obtain the absolute path of a file in the project. For example:

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".txt" #>
<#@ assembly name="EnvDTE" #>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="System.IO" #>
<# // Get the Visual Studio API as a service:
 DTE dte = ((IServiceProvider)this.Host).GetService(typeof(DTE)) as DTE;  
#>
Number of projects in this solution: <#=  dte.Solution.Projects.Count #>

<#
 // Find a path within the current project:
 string myFile = File.ReadAllText(this.Host.ResolvePath("MyFile.txt"));
#>
Content of myFile is:
<#= myFile #>

language attribute

  • Example:
    language="VB"

  • Valid values:
    C# (default)

    VB

    (The values VBv3.5 and C#v3.5 are obsolete in this release, but will be interpreted as VB and C#.)

The language attribute specifies the language (Visual Basic or Visual C#) to use for the source code in statement and expression blocks. The intermediate code file from which the output is generated will use this language. This language is not related to the language that your template generates, which can be any kind of text.

For example:

<#@ template language="VB" #>
<#@ output extension=".txt" #>
Squares of numbers:
<#
  Dim number As Integer
  For number = 1 To 4
#>
  Square of <#= number #> is <#= number * number #>
<#
  Next number
#>

inherits attribute

You can specify that the program code of your template can inherit from another class, which can also be generated from a text template.

Inheritance in a run-time (preprocessed) text template

You can use inheritance between run-time text templates to create a basic template that has several derived variants. Run-time templates are those that have the Custom Tool property set to TextTemplatingFilePreprocessor. A run-time template generates code that you can call in your application to create the text defined in the template. For more information, see Run-Time Text Generation by using Preprocessed T4 Text Templates.

If you do not specify an inherits attribute, a base class and a derived class are generated from your text template. When you specify an inherits attribute, only the derived class is generated. You can write a base class by hand, but it must provide the methods that are used by the derived class.

More typically, you specify another preprocessed template as the base class. The base template provides common blocks of text, which can be interleaved with text from the derived templates. You can use class feature blocks <#+ ... #> to define methods that contain text fragments. For example, you can place the framework of the output text in the base template, providing virtual methods that can be overridden in derived templates:

  • Run-time (preprocessed) text template BaseTemplate.tt:

    This is the common header.
    <# 
      SpecificFragment1(); 
    #>
    A common central text.
    <# 
      SpecificFragment2(); 
    #>
    This is the common footer.
    <#+ 
      // Declare abstract methods
      protected virtual void SpecificFragment1() { }
      protected virtual void SpecificFragment2() { }
    #>
    
  • Run-time (preprocessed) text template DerivedTemplate1.tt:

    <#@ template language="C#" inherits="BaseTemplate" #>
    <# 
      // Run the base template:
      base.TransformText();
    #>
    <#+
    // Provide fragments specific to this derived template:
    protected override void SpecificFragment1()
    {
    #>
       Fragment 1 for DerivedTemplate1
    <#+
    }
    protected override void SpecificFragment2()
    {
    #>
       Fragment 2 for DerivedTemplate1
    <#+
    }
    #>
    
  • Application code to invoke DerivedTemplate1:

    Console.WriteLine(new DerivedTemplate().TransformText());
    
  • Resulting output:

    This is the common header.
       Fragment 1 for DerivedTemplate1
    A common central text.
       Fragment 2 for DerivedTemplate1
    This is the common footer.
    

You can build the base and derived classes in different projects. Remember to add the base project or assembly to the derived project’s references.

You can also use an ordinary hand-written class as the base class. The base class must provide the methods used by the derived class.

Inheritance in a design-time text template

A design-time text template is a file for which Custom Tool is set to TextTemplatingFileGenerator. The template generates an output file of code or text, which forms part of your Visual Studio project. To generate the output file, the template is first translated into an intermediate program code file, which you do not usually see. The inherits attribute specifies the base class for this intermediate code.

For a design-time text template, you can specify any base class that is derived from Microsoft.VisualStudio.TextTemplating.TextTransformation. Use the <#@assembly#> directive to load the assembly or project that contains the base class.

For more information, see "Inheritance in Text Templates" in Gareth Jones’ Blog.

Change History

Date

History

Reason

March 2011

Split from parent topic.

Add compilerOptions.

Add link to text template inheritance blog entry.

Information enhancement.