Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 9 Next »

Template regions

ST introduces a finer-grained alternative to template inheritance, dubbed regions, that allow a programmer to give regions (fragments) of a template a name that may be overridden in a subgroup. (Regions are similar to something in Django). While regions are syntactic sugar on top of template inheritance, the improvement in simplicity and clarity over normal coarser-grained inheritance is substantial.

Regions allow you to mark sections of a template or leave a hole in a template that you can override or define in a subgroup without having to define a separate template. For example, imagine generating code for a method with the following template:

group Java;
method(name,code) ::= <<
public void <name>() {
    <code>
}
>>

In order to get proper separation of concerns, you would like to avoid generating debugging in your main template group. You would like to have all debugging stuff encapsulated in a debugging group. You could override the entire template but then you are duplicating all of the output literal text, which breaks the "single point of change principle." Instead of using IF conditionals around the debugging code, just leave a hole that a subgroup can override:

group Java;
method(name,code) ::= <<
public void <name>() {
    <@preamble()>
    <code>
}
>>

In a subgrammar, define the region using a fully qualified name which includes the region's surrounding template name:

group dbg : Java;
@method.preamble() ::= <<System.out.println("enter");>>

Regions are like subtemplates scoped within a template, hence, the fully-qualified name of a region is @t.r() where t is the enclosing template.

Consider another problem where you would like to replace a small portion of a larger template by creating a subgroup. Imagine you have a template that generates conditionals, but in debug mode you would like to track the fact that you evaluated an expression. Again, to avoid mingling debugging code with your main templates, you need to avoid "if dbg" type template expressions. Instead, mark the region within the template that might be replaced by debugging subgroup:

group Java;
test(expr,code) ::= "if (<@eval><expr><@end>) {<code>}"

where <@r>..<@end> marks the region called r. A subgroup can override this region:

group dbg : Java;
@test.eval() ::= "trackAndEval(<expr>)"

Regions may not have parameters, but because of the dynamic scoping of attributes, the overridden region may access all of the attributes of the surrounding template.

In an overridden region, @super.r()refers to the supergroup template's original region contents.

  • No labels