T4 Code Generation with TDS 4.0 Beta for Sitecore

Note: Content for this blog post is based on TDS 4.0 Beta and does not necessarily reflect the features of the public release

Most developers and development teams working with Sitecore will now be using some form of object mapping when working Sitecore Items programatically. This has many benefits including

  1. Working with strongly typed field values
  2. Performing CRUD operations through centralized code
  3. Abstracting Sitecore away from your domain model

Template classes typically inherit from Sitecore’s CustomItem class. From this point on you have access to the underlying Item as you would normally do but you now have the option to build wrapper code to perform operations such as returning a strongly typed fields

public class HomeItem : CustomItem
{
    public HomeItem(Item innerItem) : base(innerItem) { }

    public int NewsItemLimit
    {
        get { return Convert.ToInt32(this["News Item Limit"]); }
    }
}

HomeItem home = new HomeItem(Sitecore.Context.Item);

int newsLimit = home.NewsItemLimit;

Hand writing classes per template each containing a getter per field is a tedious and error prone approach to object mapping that can be replaced by either

  1. Writing c# code using the Sitecore API to generate classes on demand or on the item:created event
  2. Using the CustomItemGenerator by Velir for integration with the Sitecore UI
  3. Using Glass.Mapper by Mike Edwards

With the new Beta release of Team Development for Sitecore we can now leverage T4 templates (available as part of Visual Studio since Visual Studio 2005) to automatically generate classes for either of the solutions mentioned above every time we sync Sitecore with our TDS projects. Better still if using Sitecore Rocks the TDS sync happens automatically on save instead of having to use the sync window.

TDS allows us to specify a header template, a T4 template that runs only once and generates code at the top of the target file and a base template, a T4 template that executes for every item in the TDS project. All of the resulting code is merged into a single file. You can choose the name of the file and the target project you want it to appear in using the code generation tab in your TDS project properties.

TDS Code Generation Configuration

Your header template will typically be used to include using statements required by the generated code. If you don’t want templates to be executed for every item in your TDS project you can also select a template to run for a particular item and it’s descendants by using the item properties window.

T4 templates can be added to your TDS project once you have checked the enable code generation checkbox in the project properties. Once you save the project a “Code Generation Templates” item will appear

TDS Project

Selecting add new item will bring up a dialogue asking you to choose a template type. T4 templates are made up of

  1. Text Blocks
  2. Expression Blocks
  3. Control Blocks
  4. Feature blocks – control blocks cannot appear below feature blocks
Text Block

<#
	// control block
	for (int i = 0; i < length; i++)
	{
		WriteLine(i);
	}
#>

<#= WriteLine("Expression Block") #>

<#+
	public class FeatureBlock
	{
	}
#>

For each T4 item template TDS passes in a Model object of type SitecoreItem. The Model gives us access to properties of the current item for example

  1. Name
  2. Path
  3. Fields – Standard Sitecore fields that are configured in the Code Generation tab of the TDS project properties
  4. Id

SitecoreItem can be cast as SitecoreTemplate or SitecoreField which both inherit from SitecoreItem.

Once we have access to the SitecoreTemplate which also exposes base templates we have what we need to construct a simple T4 template, the following template will result in a class per template that resembles the example class above

<#@ template language="C#" debug="true" #>
<#@ import namespace="HedgehogDevelopment.SitecoreProject.VSIP.CodeGeneration.Models" #>
<#@ parameter name="Model" type="HedgehogDevelopment.SitecoreProject.VSIP.CodeGeneration.Models.SitecoreItem" #>

<#
if (Model is SitecoreTemplate)
{
var template = Model as SitecoreTemplate;
#>
namespace <#= Model.Namespace #>
{
public partial class <#= TitleCase(Model.Name) #> : CustomItem
{
public <#= className #>(Item innerItem) : base(innerItem) { }

<# foreach (var field in template.Fields) { #>
public <#= ReturnType(field.Type) #> <#= TitleCase(field.Name) #>
{
get { return this["<#= field.Name #>"]; }
}
<#}#>
	}
}
<#}#>

<#+

public string ReturnType(string typeName)
{
	if (typeName == "integer" || typeName == "number")
	{
		return "int?";
	}

return "string";
}

public string TitleCase(string name)
{
name = Regex.Replace(name, "([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))", "$1 ");
name = CultureInfo.InvariantCulture.TextInfo.ToTitleCase(name);
name = Regex.Replace(name, @"[^a-zA-Z0-9]", String.Empty);
name = Regex.Replace(name, @"(^[0-9])", "Z$1");

return name;
}
#>

Once you have a grasp of the T4 syntax and features we have a very powerful templating engine that allows us to instantly map Sitecore objects using a variety of techniques.

Happy coding!

Enhancing the Sitecore content author experience with Parameter Templates

The content author experience is central to a successful Sitecore project, striking the correct balance between functionality, tools and the reality of the everyday experience of a content author is a fine balancing act.

Sitecore provides us as developers many ways to extend the Sitecore UI using out of the box features or custom modules and applications.

With the introduction of DMS and personalization there has been a significant shift towards component driven solutions that place a great deal of importance on moving content authors away from the Sitecore Content Editor towards using the Page Editor. Allowing content authors to not only add components to a page but also configure a components behavior has become a critical requirement of many Sitecore projects.

Parameter templates give us the ability to provide a familiar user interface to content authors who are using Sitecore that enables them to decide how a component will behave by setting values in standard Sitecore fields.

For more information see the three part blog series created by myself and my colleague Jason St Cyr

  1. Introduction to Sitecore Parameter Templates: Making Sublayout configuration more intuitive
  2. Introduction to Sitecore Parameter Templates: Sitecore client configuration deep dive
  3. Introduction to Parameter Templates: Accessing Sublayout parameters using the Sitecore API

Happy Coding!