View on GitHub

semplate

Markup generation from user defined templates with semantics

How to Write a Template

Simple Templates

A simple template using GitHub flavored markdown could look like:

<!--{@template.comment}}-->

# {{title}}

By: {{author}}

Some boilerplate text

The first line specifies how comments are written in the markdown you are using. This is done by commenting out the directive {@template.comment} using the markdown’s commenting syntax. If you were using Asciidoc then you would specify this as:

//{@template.comment}}

After this, the fields of the data object you are using are specified. In this case they are title and author.

When semplate writes a markdown file using a template, these fields are replaced with the data in the data object.

A hinted at before, a template can be written in any markdown language. Here is the above example, but in Asciidoc:

    //{@template.comment}}

    = {{title}}

    By: {{author}}

    Some boilerplate text

Compound Fields

Maybe you have a data object whose fields are themselves objects, for instance:

 @Templatable
 class Customer {
     @TemplateField String name;
     @TemplateField Address address;
     // ...
 }

 @Templateable
 class Address {
     @TemplateField String street;
     @TemplateField String number;
     @TemplateField String postcode;
     @TemplateField String city;
   // ...
 }

You can refer to the address fields in a template by using a compound field name, e.g.;

Customer {{name}} lives in {{address.city}}

Compound names can be extended indefinitely.

Lists

If a data object has a field that is Iterable then you can refer to this list in the template using the ‘*’ character. For instance, the following data objects;

@Templatable
class Organisation {
    @TemplateField String name;
    @TemplateField List<Member> members;
    // ...
}

@Templatable
class Member {
    @TemplateField String name;
    @TemplateField String familyName;
    // ...
}

could be used with the following template:

# Organisation {{name}}

## Members
- {{members.*.familyName}}, {{members.*.name}}

On generating the markdown, each member would be placed on a different line.

Top Level Lists

If the data object itself implements an Iterable interface, then the first part of the compound field name is a ‘*’ character, e.g.

# Files

- {{*.name}}  {{*.size}}

Delimiters

As fields can be embedded in text, some means of identifying where in the text it is required. A template can specify a set of delimiters that are either intrinsic to the markdown or defined by the user. This definition is done using delimiter directives after the template.comment directive. For instance;

  <!--{{template.comment}}-->
  <!--{{template.delimiter.pair:"[]"}}-->
  <!--{{template.delimiter.pair:"()"}}-->
  <!--{{template.delimiter.start:": Notes "}}-->

  # Sources
  - [{{sources.*.title}}]({{sources.*.link}}) ; Notes {{sources.*.comment}}

The standard link delimiters for markdown are first specified (“[]” and “()”) followed by a user defined start delimiter “: Notes “.

Note that the template.delimiter.pair directive is a shorthand for specifying single character delimiters and could have been written as:

 <!--{{template.delimiter.start:"["}}{{template.delimiter.end:"]"}}-->