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
}
Overview¶
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:
{'name':'Alice'}
and:
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:
{{#block}}{{variable}}{{#block#Separator}},{{/block#Separator}}{{/block}}
#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.
Contents: