For those that aren’t familar with T4, here is a link to the wiki: http://en.wikipedia.org/wiki/Text_Template_Transformation_Toolkit
I like this excerpt: “T4 is used by developers as part of an application or tool framework to automate the creation of text files with a variety of parameters.”
As I started experimenting with the basics, I quickly realized that I could apply it to a ‘coding golf’ exercise some friends and I worked on. Our initial endeavor was to create a VERY simple calculator application using JavaScript, jQuery and HTML. For the calculator creation we settled on jsfiddle.net. Once we were content with our basic calculator, we copied our JavaScript into a Visual Studio 2012 project. As I looked at the original code for the calculator, I realized that T4 could write most of the redundant code for me, saving me time and risk for errors. In addition, it leaves the design of the calculator easy to extend and change. For instance, if I wanted to add scientific calculator operations later, it would be a simple matter of updating my array objects (I will show you this later).
Reducing the time one has to type redundant code is the most obvious benefit of using “template based text generation”. Of course dynamically changing code from a central location is also very nice! For those of you that can write this calculator in one line of code or shudder while looking at mine, this post isn’t for you. For those who wish to get an easy introduction to T4 with a simple example, I think you will appreciate the benefits of writing code that writes code. (Insert Xzibit Meme Here)
Part 1: Why are we doing this?
Step 1: Observe the JavaScript/jQuery calculator. I’m only showing you this code to illustrate the pattern of redundant code.
- Here is the .js code and html for the basic jQuery calculator. I’m only showing you this to illustrate the fact that the code is redundant……As you can clearly see. The difference between each function is slight. To reduce the amount of code we have to write, we’ll make a T4 template.
Input 1: <input id="input1" type="text" value="6"/> <br/> Input 2: <input id="input2" type="text" value="9"/> <br/> <input id="sum" type="button" value=" + "/> <input id= "diff" type="button" value=" - "/> <input id="div" type="button" value=" / "/> <input id= "multi" type="button" value=" * "/> <div id="output"> <div>
$("#sum").click(function () {
var x = +($("#input1").val());
var y = +($("#input2").val());
var answer = sum(x, y);
$("#output").html(answer);
});
$("#diff").click(function () {
var x = +($("#input1").val());
var y = +($("#input2").val());
var answer = diff(x, y);
$("#output").html(answer);
});
$("#div").click(function () {
var x = +($("#input1").val());
var y = +($("#input2").val());
var answer = div(x, y);
$("#output").html(answer);
});
$("#multi").click(function () {
var x = +($("#input1").val());
var y = +($("#input2").val());
var answer = multi(x, y);
$("#output").html(answer);
});
function sum(x, y) {
result = x + y;
return result;
}
function diff(x, y) {
result = x - y;
return result;
}
function div(x, y) {
result = x / y;
return result;
}
function multi(x, y) {
result = x * y;
return result;
}
Part 2: The T4 Text Template
Step 1: The Template in Visual Studio
First download Tangible T4 Editor: http://t4-editor.tangible-engineering.com/T4-Editor-Visual-T4-Editing.html and install. This little beauty will help you in many ways, not least of which is intellisense for T4 templating! Open Visual Studio. For this exercise I used VS 2012 Framework 4.5. Create a new Empty Web Application and call it T4CalcExample or something similar. Right-click on the project in the solution explorer and add new item. Under Tangible T4 Editor choose Blank T4 Template and name it Index.tt . This is important because we want it to generate index.html for us.
Step 2: Import the calculator.
Add this code to the header of your T4 Template:
<# var jquerySrc="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"; #>
AND… change the output type in the header to .html instead of .cs
SO….your header should look like this:
</pre> <# <#@ template debug="true" hostSpecific="true" #> <#@ output extension=".html" #> <#@ Assembly Name="System.Core" #> <#@ Assembly Name="System.Windows.Forms" #> <#@ import namespace="System" #> <#@ import namespace="System.IO" #> <#@ import namespace="System.Diagnostics" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Collections" #> <#@ import namespace="System.Collections.Generic" #> <# var jquerySrc="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"; #> <##> #>
The code below should be pasted below the header:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body></pre>
Input 1:
<input id="input1" type="text" value="6"/>
<br/>
Input 2:
<input id="input2" type="text" value="9"/>
<br/>
<input id="sum" type="button" value=" + "/>
<input id= "diff" type="button" value=" - "/>
<input id="div" type="button" value=" / "/>
<input id= "multi" type="button" value=" * "/>
<div id="output">
<span></span>
</div>
<pre>
<script src="<#=jquerySrc#>"></script>
<script>
$("#sum").click(function () {
var x = +($("#input1").val());
var y = +($("#input2").val());
var answer = sum(x, y);
$("#output").html(answer);
});
function sum(x, y) {
result = x + y;
return result;
}
</script>
</body>
</html>
Just to test your new T4 prowess, right-click on index.tt and choose ‘run custom tool’. Notice that an index.html file has been auto-magically added to your project and contains what you pasted into the template! This hardly shows the power of leveraging T4 but it let’s us know the moving parts are in working order.
Note: there is no need to add the rest of the functions from our calculator. We are going to let T4 handle that part for us…
Step 3: T4 helps us write repeated code patterns with subtle changes
First, reference jQuery. Cloudflare is a nice place to find reference links for minified JavaScript libraries. Next, we need to create an array that contains key,value pairs which represent each of our four operations, so:
<#
var operations = new[]{ new{ name="sum",op="+"}, new{ name="diff",op="-"}, new{ name="div",op="/"}, new{ name="multi",op="*"}};
#>
Now we need to modify our calculator to harness the power of T4. What we are doing here is saying: “For each name in our array, add that name (diff, sum, multi, div.) to the generated function, and for each operation in our array, add that symbol (+,-, x, /) to our function. T4 will generate each of our functions with the specified operators and names without having to rewrite the code ourselves.
The key here is the foreach statement and the reference to our operations array.
Here is what the final Index.tt will look like:
<#@ template debug="true" hostSpecific="true" #>
<#@ output extension=".html" #>
<#@ Assembly Name="System.Core" #>
<#@ Assembly Name="System.Windows.Forms" #>
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Diagnostics" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.Collections.Generic" #>
<# var jquerySrc="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js";
var operations = new[]{ new{ name="sum",op="+"}, new{ name="diff",op="-"}, new{ name="div",op="/"}, new{ name="multi",op="*"}};
#>
<##>
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
Input 1:
<input id="input1" type="text" value="6"/>
<br/>
Input 2:
<input id="input2" type="text" value="9"/>
<br/>
<input id="sum" type="button" value=" + "/>
<input id= "diff" type="button" value=" - "/>
<input id="div" type="button" value=" / "/>
<input id= "multi" type="button" value=" * "/>
<div id="output">
<span></span>
</div>
<script src="<#=jquerySrc#>"></script>
<script>
<# foreach(var o in operations){#>
$(<#=o.name#>).click(function () {
var x = +($("#input1").val());
var y = +($("#input2").val());
var answer = <#=o.name#>(x, y);
$("#output").html(answer);
function <#=o.name#>(x, y) {
result = x <#=o.op#> y;
return result;
}
});
<#}#>
</script>
</body>
</html>
Step 4: Run this baby and enjoy your first code generator app!
Should look something like:
ENJOY!!!
