Expressions

Table of Contents for Expressions

Expressions

Attribute References

Named attributes

The most common thing in a template besides plain text is a simple named attribute reference such as:

Your email: $email$

The template will look up the value of email and insert it into the output stream when you ask the template to print itself out. If email has no value, then it evaluates to the empty string and nothing is printed out for that attribute expression. When working with group files, if email is not defined in the formal parameter list of an enclosing template, an exception is thrown.

If the attribute is multi-value such as an instance of a list, the elements are emitted without separator one after the other. If there are null values in the list, these are ignored by default. Given template $values$ with attribute values=9,6,null,2,null then the output would be:

962

To use a separator in between those multiple values, use the separator option:

$values; separator=", "$

The output would be:

9, 6, 2

To emit a special value for each null element in a list, use the null option:

$values; null="-1", separator=", "$

Again using values=9,6,null,2,null then the output would be:

9, 6, -1, 2, -1

Property references

If a named attribute is an aggregate with a property or a simple data field, you may reference that property using attribute.property. For example:

Your name: $person.name$
Your email: $person.email$

StringTemplate ignores the actual object type stored in attribute person and simply looks for one of the following via reflection (in search order):

Java

  1. A method named getName()
  2. A method named isName() - StringTemplate accepts isName() if it returns a Boolean
    If found, a return value is obtained via reflection. The person.email expression is resolved in a similar manner.
    If the property is not accessible ala JavaBeans, StringTemplate attempts to find a field with the same name as the property. In the above example, StringTemplate would look for fields name and email without the capitalization used with JavaBeans property access methods

C#

  1. a C# property (i.e. a non-indexed CLR property) named name
  2. A method named get_name()
  3. A method named Getname()
  4. A method named Isname()
  5. A method named getname()
  6. A method named isname()
  7. A field named name
  8. A C# indexer (i.e. a CLR indexed property) that accepts a single string parameter - this["name"]
    If found, a return value is obtained via reflection. The person.email expression is resolved in a similar manner.
    As shown above, if the property is not accessible as a C# property, StringTemplate attempts to find a field with the same name as the property. In the above example, StringTemplate would look for fields name and email without the capitalization typically used with property access methods.

Python

  1. A method named getName()
  2. A method named isName() - StringTemplate accepts isName() if it returns a Boolean
    If found, a return value is obtained via reflection. The person.email expression is resolved in a similar manner.
    If the property is not accessible ala JavaBeans, StringTemplate attempts to find a field with the same name as the property. In the above example, StringTemplate would look for fields name and email without the capitalization used with JavaBeans property access methods

An exception is thrown if that property is not defined on the target object.

Because the type is ignored, you can pass in whatever existing aggregate (class) you have such as User or Person:

Java

User u = database.lookupPerson("parrt@jguru.com");
st.setAttribute("person", u);

C#

User u = database.LookupPerson("parrt@jguru.com");
st.SetAttribute("person", u);

Python

u = database.lookupPerson("parrt@jguru.com")
st["person"] = u

Or, if a suitable aggregate doesn't exist, you can make a connector or "glue" object and pass that in instead:

Java

st.setAttribute("person", new Connector());

C#

st.SetAttribute("person", new Connector());

Python

st["person"] = Connector()

where Connector is defined as:

Java

public class Connector {
    public String getName() { return "Terence"; }
    public String getEmail() { return "parrt@jguru.com"; }
}

C#

public class Connector {
    public string Name  { get {return "Terence";} }
    public string Email { get { return "parrt@jguru.com";} }
}

Python

class Connector(object):
    def getName(self):
        return "Terence"

    def getEmail(self):
        return "parrt@jguru.com"

The ability to reference aggregrate properties saves you the trouble of having to pull out the properties with code like this:

Java

User u = database.lookupPerson("parrt@jguru.com");
st.setAttribute("name", u.getName());
st.setAttribute("email", u.getEmail());

C#

User u = database.lookupPerson("parrt@jguru.com");
st.SetAttribute("name", u.Name);
st.SetAttribute("email", u.Email);

Python

u = database.lookupPerson("parrt@jguru.com")
st["name"] = u.getName()
st["email"] = u.getEmail()

and having template:

Your name: $name$
Your email: $email$

The latter is more widely applicable and totally decoupled from code and logic; i.e., it's "better" but much less convenient. Be very careful that the property methods do not have any side-effects like updating a counter or whatever. This breaks the rule of order of evaluation independence.

Indirect property names

Sometimes the property name is itself variable, in which case you need to use indirect property access notation:

$person.(propertyName)$

where propertyName is an attribute whose value is the name of a property to fetch from person. Using the examples from above, propertyName could hold the value of either name or email.

propertyName may actually be an expression instead of a simple attribute name.

Map key/value pair access

Java

You may pass in instances of any object that implements the Map interface. Rather than creating an aggregate object (though automatic aggregate creation is discussed in the next section) you can pass in a HashMap that has keys referencable within templates. For example,

StringTemplate a = new StringTemplate("$user.name$, $user.phone$");
HashMap user = new HashMap();
user.put("name", "Terence");
user.put("phone", "none-of-your-business");
a.setAttribute("user", user);
String results = a.toString();


yields a result of "Terence, none-of-your-business".

C#

You may pass in instances of type Hashtable and ListDictionary but cannot pass in objects implementing the IDictionary interface because that would allow all sorts of wacky stuff like database access. Rather than creating an aggregate object (though automatic aggregate creation is discussed in the next section) you can pass in a Hashtable that has keys referencable within templates. For example,

StringTemplate a = new StringTemplate("$user.name$, $user.phone$");
Hashtable user = new Hashtable();
user.Add("name", "Terence");
user.Add("phone", "none-of-your-business");
a.SetAttribute("user", user);
string results = a.ToString();


yields a result of "Terence, none-of-your-business".

Python

You may pass in instances of type dict. Rather than creating an aggregate object (though automatic aggregate creation is discussed in the next section) you can pass in a dict that has keys referencable within templates. For example,

a = stringtemplate3.StringTemplate("$user.name$, $user.phone$")
user = {}
user["name"] = "Terence"
user["phone"] = "none-of-your-business"
a["user"] = user
results = str(a)


yields a result of "Terence, none-of-your-business".

StringTemplate interprets Map objects to have two predefined properties: keys and values that yield a list of all keys and the list of all values, respectively. When applying a template to a map, StringTemplate iterates over the values so that <aMap> is a shorthand for <aMap.values>. Similarly <aMap.keys> walks over the keys. You can list all of the elements in a map like this:

<aMap.keys:{k| <k> maps to <aMap.(k)>}>.

Note the use of the indirect property reference <aMap.(k)>, which says to take the value of the k as the key in the lookup. Clearly without the parentheses the normal map lookup mechanism would treat k as a literal and try to look up k in the map.  Also note that the map must have keys that are Strings for indirect property referencing to work, because the key is first rendered into a string by ST and then that is used to look up the value in the map.

Difficult property names

Some property names cause parse errors because of clashes with built in keywords or because they do not match the rules for IDs as used by String Template. These difficult property names can be dealt with by quoting the property name in combination with the indirect property construct:

$person.("first")$       --- Build in keyword
$person.("1")$           --- non ID conforment name

Difficult properties names are quite likely to occur when dealing with maps. Map keys can be defined using arbitrary strings, including spaces and syntax characters used to defined templates themselves.

Be careful that the keys are the appropriate type. If person keys are Integer, $person.("1")$ won't work as Strings are never Integers.

Automatic aggregate creation

Creating one-off data aggregates is a pain, you have to define a new class just to associate two pieces of data. StringTemplate makes it easy to group data during setAttribute() calls. You may pass in an aggregrate attribute name to setAttribute() with the data to aggregate:

Java

StringTemplate st = new StringTemplate("$items:{$it.(\"last\")$, $it.(\"first\")$\n}$");
st.setAttribute("items.{first,last}", "John", "Smith");
st.setAttribute("items.{first,last}", "Baron", "Von Munchhausen");
String expecting =
        "Smith, John\n" +
        "Von Munchhausen, Baron\n";

C#

StringTemplate st = new StringTemplate("$items:{$it.(\"last\")$, $it.(\"first\")$\n}$");
st.SetAttribute("items.{first,last}", "John", "Smith");
st.SetAttribute("items.{first,last}", "Baron", "Von Munchhausen");
string expecting = "Smith, John\n" +
                   "Von Munchhausen, Baron\n";

Python

st = stringtemplate3.StringTemplate("$items:{$it.(\"last\")$, $it.(\"first\")$\n}$")
st.setAttribute("items.{first,last}", "John", "Smith")
st.setAttribute("items.{first,last}", "Baron", "Von Munchhausen")
expecting = \
   "Smith, John\n" + \
   "Von Munchhausen, Baron\n"

Note that the template, st, expects the items to be aggregates with properties first and last. By using attribute name

items.{first,last}

You are telling StringTemplate to take the following two arguments as properties first and last.

The various overloads of the setAttribute() method can handle from 1 to 5 arguments. The C# version uses variable-length argument list (using params keyword).

List construction

As of v2.2, you may combine multiple attributes into a single multi-valued attribute in a syntax similar to the group map feature. Concatenate attributes by placing them in square brackets in a comma-separated list. For example,

$[mine,yours]$

creates a new multi-valued attribute (a list) with both elements - all of mine first then all of yours. This feature is handy when the model happens to group attributes differently than you need to access them in the view. This ability to rearrange attributes is consistent with model-view separation because the template cannot alter the data structure nor test its values - the template is merely looking at the data from a new perspective.

Naturally you may combine the list construction with template application:

$[mine,yours]:{ v | ...}$

Note that this is very different from

$mine,yours:{ x,y | ...}$

which iterates max(n,m) times where n and m are the lengths of mine and yours, respectively. The [mine,yours] version iterates n+m times.

Template References

You may reference other templates to have them included just like the C language preprocessor #include construct behaves. For example, if you are building a web page (page.st) that has a search box, you might want the search box stored in a separate template file, say, searchbox.st. This has two advantages:

  • You can reuse the template over and over (no cut/paste)
  • You can change one template and all search boxes change on the whole site.

Using method call syntax, just reference the foreign template:

<html>
<body>
...
$searchbox()$
...
</body>
</html>

The invoking code would still just create the overall page and the enclosing page template would automatically create an instance of the referenced template and insert it:

Java

StringTemplateGroup group = new StringTemplateGroup("webpages", "/usr/local/site/templates");
StringTemplate page = group.getInstanceOf("page");

C#

StringTemplateGroup group = new StringTemplateGroup("webpages", "C:/Inetpub/wwwroot/site/templates");
StringTemplate page = group.GetInstanceOf("page");

Python

group = stringtemplate3.StringTemplateGroup("webpages", "/usr/local/site/templates")
page = group.getInstanceOf("page")

If the template you want to reference, say searchbox, is in a subdirectory of the StringTemplateGroup root directory called misc, then you must reference the template as: misc/searchbox().

The included template may access attributes. How can you set the attribute of an included template? There are two ways: inheriting attributes and passing parameters.

Accessing Attributes Of Enclosing Template

Any included template can reference the attributes of the enclosing template instance. So if searchbox references an attribute called resource:

<form ...>
...
<input type=hidden name=resource value=$resource$>
...
</form>

you could set attribute resource in the enclosing template page object:

Java

StringTemplate page = group.getInstanceOf("page");
page.setAttribute("resource", "faqs");

C#

StringTemplate page = group.GetInstanceOf("page");
page.SetAttribute("resource", "faqs");

Python

page = group.getInstanceOf("page")
page["resource"] = "faqs"

This "inheritance" (dynamic scoping really) of attributes feature is particularly handy for setting generally useful attributes like siteFontTag in the outermost body template and being able to reference it in any nested template in the body.

Passing Parameters To Another Template

Another, more obvious, way to set the attributes of an included template is to pass in values as parameters, making them look like C macro invocations rather than includes. The syntax looks like a set of attribute assignments:

<html>
<body>
...
$searchbox(resource="faqs")$
...
</body>
</html>

where I am setting the attribute of the included searchbox to be the string literal "faqs".

The right-hand-side of the assignment may be any expression such as an attribute reference or even a reference to another template like this:

$boldMe(item=copyrightNotice())$

You may also use an anonymous template such as:

$bold(it={$firstName$ $lastName$})$

which first computes the template argument and then assigns it to it.

If you are using StringTemplate groups, then you have formal parameters and for those templates with a sole formal argument, you can pass just an expression instead of doing an assignment to the argument name. For example, if you do $bold(name)$ and bold has one formal argument called item, then item gets the value of name just as if you had said {$bold(item=name)$}.

Allowing enclosing attributes to pass through

When template x calls template y, the formal arguments of y hide any x arguments of the same because the formal parameters force you to define values. This prevents surprises and makes it easy to ensure any parameter value is empty unless you specifically set it for that template. The problem is that you need to factor templates sometimes and want to refine behavior with a subclass or just invoke another shared template but invoking y as <y()> hides all of x's parameters with the same name. Use <y(...)> syntax to indicate y should inherit all values even those with the same name. <y(name="foo", ...)> would set one arg, but the others are inherited whereas <y(name="foo")> only has name set; all other arguments of template y are empty. You can set manually with:

Java

StringTemplate.setPassThroughAttributes()

C#

StringTemplate.SetPassThroughAttributes()

Python

st.passThroughAttributes = True

Argument evaluation scope

The right-hand-side of the argument assignments are evaluated within the scope of the enclosing template whereas the left-hand-side attribute name is the name of an attribute in the target template. Template invocations like $bold(item=item)$ actually make sense because the item on the right is evaluated in a different scope.

Attribute operators

StringTemplate provides a number of operators that you can apply to attributes to get a new view of that data: first, rest, last, length, strip.

Sometimes you need to treat the first or last element of multi-valued attribute differently than the others. For example, if you have a list of integers in an attribute and you need to generate code to sum those numbers, you could start like this:

<numbers:{ n | sum += <n>;}>

You need to define sum, however:

int sum = 0;
<numbers:{ n | sum += <n>;}>

What if numbers is empty though? No need to create the sum definition so you could do this:

<if(numbers)>int sum = 0;<endif>
<numbers:{ n | sum += <n>;}>

A more specific strategy (and one that generates slightly better code as it avoids an unnecessary initialization to 0) is the following:

<first(numbers):{ n | int sum = <n>;}>
<rest(numbers):{ n | sum += <n>;}>

where first(numbers) results in the first value of attribute numbers if any and rest(numbers) results all values in numbers but the first value.

The other operator available to you is last, which naturally results in the last value of a multi-valued attribute.  Now we have trunc also which returns all but the last value.

Special cases:

  • operations on empty attributes yields an empty value
  • rest of a single-valued attribute yields an empty value
  • tail of a single-valued attribute yields the same as first, the attribute value

You may find it handy to use another operator sometimes: plus "string concatenate". operator. For example, you may want to compute an argument to a template using a literal and an attribute:

...$link(url="/faq/view?ID="+faqid, title=faqtitle)$...

where faqid and faqtitle are attributes you have set for
the template that referenced link.

Terence says

I'm a little uncomfortable with this concatenation operation. Please use a template instead

:

...$link(url={/faq/view?ID=$faqid$}, title=faqtitle)$...

In order to emit the number of attributes in a single or multi-value attribute, use the length operator:

int data[$length(x)$] = { $x; separator=", "$ };

In this example, with x=5,2,9 the following would be emitted:

int data[3] = { 5, 2, 9 };

Null values are counted by length but you can use the strip operator to return a new view of your list without null values:

int data[$length(strip(x))] = { $x; separator=", "$ };

Template Application

Imagine a simple template called bold:

<b>$item$</b>

Just as with template link described above, you can reference it from a template by invoking it like a method call:

$bold(item=name)$

What if you want something bold and italicized? You could simply nest the template reference:

$bold(item=italics(item=name))$

(or $bold(italics(name))$ if you're using group file format and have formal parameters). Template italics is defined as:

<i>$item$</i>

using a different attribute with the same name, item; the attributes have different values just like you would expect if these template references where method calls in say Java or C# and, item was a local variable. Parameters and attribute references are scoped like a programming language.

Think about what you are really trying to say here. You want to say "make name italics and then make it bold", or "apply italics to the name and then apply bold." There is an "apply template" syntax that is a literal translation:

$name:italics():bold()$

where the templates are applied in the order specified from left to right. This is much more clear, particularly if you had three templates to apply:

$name:courierFont():italics():bold()$

For this syntax to work, however, the applied templates have to reference a standard attribute because you are not setting the attribute in a parameter assignment. In general for syntax expr:template(), an attribute called it is set to the value of expr. So, the definition of bold (and analogously italics), would have to be:

<b>$it$</b>

to pick up the value of name in our examples above.

As of 2.2 StringTemplate, you can avoid using it as a default parameter by using formal arguments. For expression $x:y()$, StringTemplate will assign the value of x to it and any sole formal argument of y. For example, if y is:

y(item) ::= "_$item$_"

then item would also have the value of x.

If the attribute to which you are applying a template is null (i.e., missing), then the application is not done as there is no work to do. Optionally, you can specify what string template should display when the attribute is null a using the null option:

$name:bold(); null="n/a"$

That is equivalent to the following conditional:

$if(name)$$name:bold()$$else$n/a$endif$

Applying Templates To Multi-Valued Attributes

Where template application really shines though is when an attribute is multi-valued. One of the most common web page generation issues is making lists of items either as bullet lists or table rows etc... Applying a template to a multi-valued attribute means that you want the template applied to each of the values.

Consider a list of names (i.e., you set attribute names multiple times) that you want in a bullet list. If you have a template called listItem:

<li>$it$</li>

then you can do this:

<ul>
$names:listItem()$
</ul>

and each name will appear as a bullet item. For example, if you set names to "Terence", "Tom", and "Kunle", then you would see:

<ul>
<li>Terence</li>
<li>Tom</li>
<li>Kunle</li>
</ul>

in the output.

Whenever you apply a template to an attribute or multi-valued attribute, the default attribute it is set. Similarly, attributes i and i0 (since v3.0) of type integer are set to the value's index number starting from 1 (i0 starts from 0). For example, if you wanted to make your own style of numbered list, you could reference i to get the index:

$names:numberedListItem()$

where template numberedListItem is defined as:

$i$. $it$<br>

In this case, the output would be:

1. Terence<br>
2. Tom<br>
3. Kunle<br>

If there is only one attribute value, then i will be 1. However, if template numberedListItem is defined as:

$i0$. $it$<br>

The output would be:

0. Terence<br>
1. Tom<br>
2. Kunle<br>

As when invoking templates ala "includes", a single formal argument is also set to the iterated value. For example, you could define numberedListItem as follows in a StringTemplateGroup file:

numberedListItem(item) ::= "$i$. $item$<br>"

Templates are not applied to null values in multi-valued attributes. StringTemplate behaves as if those values simply did not exist in the list. To emit a special string or template for each null value, use the null option:

$names:bold(); null="n/a"$

which will emit "n/a" for any null value in attribute names.

Applying Multiple Templates To Multi-Valued Attributes

The result of applying a template to a multi-valued attribute is another multi-valued attribute containing the results of the application. You may apply another template to the results of the first template application, which comes in handy when you need to format the elements of a list before they go into the list. For example, to bold the elements of a list do the following (given the appropriate template definitions from above):

$names:bold():listItem()$

If you actually want to apply a template to the combined (string) result of a previous template application, enclose the previous application in parenthesis. The parenthesis will force immediate evaluation of the template application, resulting in a string. For example,

$(names:bold()):listItem()$

results in a single list item full of a bunch of bolded names. Without the parenthesis, you get a list of items that are bolded.

Applying Alternating Templates To Multi-Valued Attributes

When generating lists of things, you often need to change the color or other formatting instructions depending on the list position. For example, you might want to alternate the color of the background for the elements of a list. The easiest and most natural way to specify this is with an alternating list of templates to apply to an expression of the form: $expr:t1(),t2(),...,tN()$. To make an alternating list of blue and green names, you might say:

$names:blueListItem(),greenListItem()$

where presumably blueListItem template is an HTML <table> or something that lets you change background color. names[0] would get blueListItem() applied to it, names[1] would get greenListItem(), and names[2] would get blueListItem() again, etc...

If names is single-valued, then blueListItem() is applied and that's it.

Applying Anonymous Templates

Some templates are so simple or so unlikely to be reused that it seems a waste of time making a separate template file and then referencing it. StringTemplate provides anonymous subtemplates to handle this case. The templates are anonymous in the sense that they are not named; they are directly applied in a single instance.

For example, to show a name list do the following:

<ul>
$names:{<li>$it$</li>}$
</ul>

where anything enclosed in curlies is an anonymous subtemplate if, of course, it's within an attribute expression. Note that in the subtemplate, I must enclose the it reference in the template expression delimiters. You have started a new template exactly like the surrounding template and you must distinguish between text and attribute expressions.

You can apply multiple templates very conveniently. Here is the bold list of names again with anonymous templates:

<ul>
$names:{<b>$it$</b>}:{<li>$it$</li>}$
</ul>

The output would look like:

<ul>
<li><b>Terence</b></li>
<li><b>Tom</b></li>
<li><b>Kunle</b></li>
</ul>

Anonymous templates work on single-valued attributes as well.

As of 2.2, you may define formal arguments on anonymous templates even if you are not using StringTemplate groups. This syntax is borrowed from Smalltalk though it is identical in function to lambda of Python. Use a comma-separated list of argument names followed by the '|' "pipe" symbol. Any single whitespace character immediately following the pipe is ignored. The following example bolds the names in a list using an argument to avoid the monotonous use of it:

<ul>
$names:{ n | <b>$n$</b>}$
</ul>

Clearly only one argument may be defined in this situation: the iterated value of a single list.

Anonymous template application to multiple attributes

In some cases, the model may present data to the view as separate columns of data rather than as a single list of objects, such as multi-valued attributes names and phones rather than a single users multi-valued attribute. As of 2.2, you may iterate over multiple attributes:

$names,phones:{ n,p | $n$: $p$}$

An error is generated if you have too many arguments for the number of attributes. Iteration proceeds while at least one of the attributes (names or phones, in this case) has values.

Indirect template references

Sometimes the name of the template you would like to include is itself a variable. So, rather than using "<item:format()>" you want the name of the template, format, to be a variable rather than a literal. Just enclose the template name in parenthesis to indicate you want the immediate value of that attribute and then add () like a normal template invocation and you get "<item:(someFormat)()>", which means "look up attribute someFormat and use its value as a template name; appy to item." This deliberately looks similar to the C function call indirection through a function pointer (e.g., "(*fp)()" where fp is a pointer to a function). A better way to look at it though is that the (someFormat) implies immediately evaluate someFormat and use as the template name.

Usually this "variable template" situation occurs when you have a list of items to format and each element may require a different template. Rather than have the controller code create a bunch of instances, one could consider it better to have StringTemplate do the creation--the controller just names what format to use.

If StringTemplate did not have a map definition, you could simulate its functionality. Consider generating a list of C# declarations that are initialized to 0, false, null, etc... You could define a template for int, Object, Array, etc... declarations and then pass in an aggregate object that has the variable declaration object and the format. In a template group file you might have:

group Java;

file(variables,methods) ::= <<
<variables:{ v | <v.decl:(v.format)()>}; separator="\n">
<methods>
\>>
intdecl(decl) ::= "int <decl.name> = 0;"
intarray(decl) ::= "int[] <decl.name> = null;"

Your code might look like:

Java

StringTemplateGroup group =
        new StringTemplateGroup(new StringReader(templates),
                AngleBracketTemplateLexer.class);
StringTemplate f = group.getInstanceOf("file");
f.setAttribute("variables.{decl,format}", new Decl("i","int"), "intdecl");
f.setAttribute("variables.{decl,format}", new Decl("a","int-array"), "intarray");
System.out.println("f="+f);
String expecting = ""+newline+newline;

C#

StringTemplateGroup group =
        new StringTemplateGroup(new StringReader(templates),
                typeof(AngleBracketTemplateLexer));
StringTemplate f = group.GetInstanceOf("file");
f.setAttribute("variables.{decl,format}", new Decl("i","int"), "intdecl");
f.setAttribute("variables.{decl,format}", new Decl("a","int-array"), "intarray");
Console.Out.WriteLine("f="+f);
string expecting = ""+newline+newline;

Python

group = stringtemplate3.StringTemplateGroup(file=StringIO(templates), lexer="angle-bracket")
f = group.getInstanceOf("file")
f.setAttribute("variables.{decl,format}", Decl("i","int"), "intdecl")
f.setAttribute("variables.{decl,format}", Decl("a","int-array"), "intarray")
print "f =", f
expecting = ""+os.linesep

For this simple unit test, the following dummy decl class is used:

Java

public static class Decl {
    String name;
    String type;
    public Decl(String name, String type) {this.name=name; this.type=type;}
    public String getName() {return name;}
    public String getType() {return type;}
}

C#

public class Decl {
    string name;
    string type;
    public Decl(string name, string type) {this.name=name; this.type=type;}
    public string Name { get {return name;} }
    public string Type { get {return type;} }
}

Python

class Decl(object):
    def __init__(self, name, type_):
        self.name = name
        self.type = type_

    def getName(self):
        return self.name

    def getType(self):
        return self.type

The value of f.ToString() is:

int i = 0;
int[] a = null;

Missing attributes (i.e., null valued attributes) used as indirect template attribute generate nothing just like referencing a missing attribute.