Welcome to Lina

Lina is a minimal template system for Python, modelled after Google’s CTemplate library. It is designed to provide fast, safe template evaluation to generate code or other text documents.:

enum DataTypes {
{{#types:list-separator=,NEWLINE}}  {{name}}={{value:hex}}{{/types}}

evaluated with:

formats = [{'name':'Vector3i', value: 0x301}, {'name':'Vector3f', 'value': 0x302}]

will produce:

enum DataTypes {
    Vector3i = 0x301,
    Vector3f = 0x302


The base class in Lina is lina.Template which must be initialized with the template contents. It can be then evaluated to a string using lina.Template.Render() and lina.Template.RenderSimple().

Lina has two main directives, values and blocks. A value is something which is replaced directly by the provided value, while a block is used to iterate over collections. Both blocks and values can be optionally formatted using a formatter, which allows for example to turn a string into uppercase inside the template.

Values are escaped using double curly braces:

Hello {{name}}!

Blocks have an additional prefix before the variable, # for the block start and / for the block end:

{{#users}}Hello {{name}}!{{/users}}

This requires to pass an array of named objects:

template.Render ({'users':[{'name':'Alice'}, {'name':'Bob'}]})

In some cases, this is unnecessary complicated. Lina provides a special syntax to access the current element, using a single dot. The template aboves can be then simplified to:

{{#users}}Hello {{.}}!{{/users}}

and rendered with:

template.Render ({'users': ['Alice', 'Bob']})

or even simpler using lina.Template.RenderSimple():

template.RenderSimple (users = ['Alice', 'Bob'])

Both self-references as well as items can also access fields of an object. Assuming the User class has fields name, age, the follwing template will print the user name and age:

{{#users}}Hello {{.name}}, you are {{.age}} years old!{{/users}}

The field accessor syntax works for both fields as well as associative container, that is, for Lina, the following two objects are equivalent:



class User:
    def __init__(self, name):
        self.name = name

For blocks, Lina provides additional modifiers to check whether the current block execution is the first, an intermediate or the last one:


#First will be only expanded for the first iteration, #Separator will be expanded for every expansion which is neither first nor last and #Last will be expanded for the last iteration only. If there is only one element, it will considered both first and last item of the sequence.


Indices and tables