Lighty-template is very simple template engine for python (python.org). Template syntax looks like django-template or jinja2 template. But template engine code is easier and gives a way to write all needed tags without any hacks.
Now it does not include all features django-template or jinja2 supports, but I’ll try to fix it as soon as possible.
Simple template example (let’s call it index.html):
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
{% block style %}{% endblock %}
{% block script %}{% endblock %}
</head>
<body>
{% block content %}
<h1>Hello, world!</h1>
<p>Some text here</p>
{% endblock %}
</body>
</html>
You can load you templates using templates loader. Usualy you need to use FSLoader class::
from lighty.templates.loaders import FSLoader
loader = FSLoader(['tests/templates'])
template = loader.get_template('index.html')
Above code means that we create new FSLoader that discover templates in path ‘tests/templates’. If we place our ‘index.html’ template into this path this code can works fine and we can render template with some context::
result = template.execute({'title': 'Page title'})
or just:
result = template({'title': 'Page title'})
Note that if there is no variable ‘title’ specified in context template raises exception. Lighty-template is strict template engine requires to be carefull with your templates and variables in context for rendering. I think that usually strict means better and safe.
Methods for context accessing
Package provides template filters management
Package provides template loaders
Bases: lighty.templates.loaders.TemplateLoader
Class provides methods for template managing
Package provides template tags manager and base tags list
Module provides template two template classes:
Bases: lighty.templates.template.Template
Lazy template class change the way how template loaded. :class: Template parses template context on template creation if template text provided:
>>> from lighty.templates.template import Template, LazyTemplate
>>> template = Template('{{ var }}') # template already parsed
>>> template.commands
[<function print_variable at 0xdda0c8>]
>>> lazy = LazyTemplate('{{ var }}') # not parsed
>>> lazy.commands
[]
>>> lazy.execute({'var': 'test'}) # parse on demand and then execute
'test'
>>> lazy.commands
[<function print_variable at 0x1130140>]
Lazy template class usefull for template loaders like a :class: lighty.templates.loader.FSLoader that requires to get the list of all the templates but does not require to parse all the templates on loading because it causes an error with templates loading order (when child template loaded before parent). Also it speed ups templates loading process because it does not require to parse all the templates when they even not used.
Bases: object
Class represents template. You can create template directrly in code:
template = Template('<b>Hello, {{ name }}!</b>')
or load it using template loader:
template = loader.get_template('simple.html')
Also you can create template and parse some text later but I do not recomend to do that:
template = Template() template.parse({{ var }})
To render the template you can use execute method and pass render context as single arguments to this methods::
template.execute({'var': 'test'})
And you reciveve ‘test’ string as result of template execution. Or you can just call the template like a function to render template simpler way::
template({'var': 'test'})
You can also access more complex variable in you context from templates, as example dict subclasses or even object fields::
>>> template = Template('Hello, {{ user.name }} from {{ var }}')
>>> template({'user': {'name': 'Peter', 'is_authenticated': True},
... 'var': 'test'})
'Hello, Peter from test'
Execute all commands on a specified context
Package contains default template tags
Make pretty float representation
>>> print floatformat(a)
12
>>> print floatformat(a, '2')
12.40
>>> print floatformat(a, '-2')
12.4
Round a float value according to math rules
>>> print floatround(a)
12
>>> print floatround(a, '1')
12.5
Join list or items with joiner
>>> join([1, 2, 3], ' ')
'1 2 3'
Return’s the length of the string, dict or list
Formats the variable according to the format, a string formatting specifier.
This specifier uses Python string formating syntax, with the exception that the leading “%” is dropped.
See http://docs.python.org/lib/typesseq-strings.html for documentation of Python string formatting
Basic template tags library
Class for executing block in loop with a context update
Block tag. This tag provides method to modify chilren template for template inheritance.
As example for base template called ‘base.html’
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
{% block head %}{% endblock %}
</head>
<body>
{% block content %}Some contents{% endblock %}
</body>
</html>
and extended template called ‘extended.html’
{% extend "base.html" %}
{% block head %}<style></style>{% endblock %}
{% block content %}<h1>Hello, world!</h1>{% endblock %}
we can execute extended template with additional context:
template = loader.get_template('extended.html')
template({'title': 'Hello'})
to get something similar to this:
<!DOCTYPE html>
<html>
<head>
<title>%s</title>
<style></style>
</head>
<body>
<h1>Hello, world!</h1>
</body>
</html>
Helper function that can be used in block tags to execute inner template code on a specified context
Execute function with context switching
Tag used to create tamplates iheritance. To get more information about templates inheritance see block().
Find command in commands list
For tag used to make loops over all the iterator-like objects.
Example:
{% for a in items %}{{ a }}{% endfor %}
returns for items = [1, 2, 3]:
123
Also forloop variable will be added into scope. It contains few flags can be used to render customized templates:
{% for a in items %}
{% spaceless %}<span
{% if forloop.first %} class="first"{% endif %}
{% if forloop.last %} class="last"{% endif %}>
{{ forloop.counter0 }}.
{{ forloop.counter }} from {{ forloop.total }}
</span>{% endspaceless %}
{% endfor %}
returns:
<span class="first">0. 1 from 3</span>
<span>1. 2 from 3</span>
<span class="last">2. 3 from 3</span>
Get parent blocks
If tag can brings some logic into template. Now it’s has very simple implementations that only checks is variable equivalent of True. There is no way to add additional logic like comparisions or boolean expressions. Hope I’ll add this in future.
Example:
{% if user.is_authenticated %}Hello, {{ user.name }}!{% endif %}
returns for user = {‘is_authenticated’: True, ‘name’: ‘Peter’}:
Hello, Peter!
TODO:
- add else
- add conditions
This tag includes another template inside current position
Example:
<html>
<head>
{% include "includes/stylesheets.html" %}
</head>
<body>
{% include "includes/top_nav.html" %}
{% block content %}{% endblock %}
</body>
Search for command in commands list and replace it with a new one
This tag removes unused spaces
Template:
{% spaceless %}
Some
text
{% endspaceless %}
will be rendered to:
Some text
With tag can be used to set the shorter name for variable used few times
Example:
{% with request.context.user.name as user_name %}
<h1>{{ user_name }}'s profile</h1>
<span>Hello, {{ user_name }}</span>
<form action="update_profile" method="post">
<label>Your name:</label>
<input type="text" name="user_name" value="{{ user_name }}" />
<input type="submit" value="Update profile" />
</form>
{% endwith %}