Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Clarifications

...

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). (Regions are similar to a feature in Django). This feature allows a programmer to mark a location or series of lines in a template, and give it a name. A subgroup which inherits this template can provide replacement code to override just the named region. This avoids having to override the supergroup's template with a whole replacement template, when just a small addition or replacement is needed. 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

Add text at a location

For example, in a code-generation scenario, imagine using the following template called method to produce the text for a method:

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

...

Suppose that you want also want the method template to be able to optionally generate method code that includes debugging statements. (To be clear about this example: this would be debugging code to debug the generated Java method, not code to debug the template itself.)

You could employ conditionally included subtemplates (using <if(...)> etc)  around the debugging lines, but that clutters up the templates of the Java group considerably, and also fails to achieve proper separation of concerns, you would like to avoid generating debugging in your main template group. You .

Instead you would like to have all debugging stuff encapsulated in a separate template group which focuses on debugging group. You could override the entire template but . In that template group, you could create an overriding method template by copying and pasting the entire method template and inserting your additions. But then you are duplicating all of the that output literal text, which breaks the "single point of change principle." Instead of using IF conditionals around the debugging code,

Instead just leave a hole that a subgroup can override, here a location marked with <@preamble()>:

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

In a subgrammartemplate subgroup focusing on debugging (group dbg), define the region using a fully qualified name which includes the region's surrounding template name, @method.preamble(), and supply the replacement text:

No Format
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 and r is the region name.

Replace a region of existing template text

Consider another problem where you would like, in a template subgroup, to replace a small portion of a larger template by creating a subgrouplarge inherited template. Imagine you have a template that generates conditionalsconditional statements in the output language, but in debug mode you would also like to be able to generate a debug version of these statements which track the fact that you evaluated an expression. an expression was evaluated.

(To be clear about this example, here the template's purpose is to produce "if" statements in the output language, here Java. That "if" is unrelated to the issue of using template <if(...)> expressions, which we are discussing how to avoid.)

Again, to avoid mingling debugging debug version code with your main templates, you need want to avoid "if dbg" type template expressions. Instead, mark the region within the template that might be replaced by debugging subgroupan inheriting subgroup focusing on debugging. Here the code is marked with the pair of markers <@eval>...<@end>:

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

where <@r>..<@end> marks the region called r. A Now a template subgroup can override (replace) this region:

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

...

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

(I'm guessing this is trying to say: Within the replacement template text, ie: right-hand-side, you can use the symbol @super.r() to insert the original region contents.  Also guessing that "super" is a keyword, and should not be replaced, while "r" should be replaced with the actual region name. Pretty sure this needs to be enclosed in expression delimiters, not just bare. -- GW)