lighty.templates Package (Lighty Templates system)

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.

Features

  • Stupid simple syntax almost compatible with django-template.
  • Pure python.
  • Supports both Python 2 (checked with 2.7.2) and Python 3 (checked with 3.2.2)
  • Fast. From 3 to 10 times faster than django-template and even faster on some benchmarks than jinja2 (but in one benchmark 2 times slower).
  • Simple and compact code.
  • Template filters with multiply arguments.
  • Basic template filters included (now just 14 template filters).
  • Basic template tags included.
  • Simple but powerfull tag declaration - it’s easy to create your own block tags with writing single function.
  • Custom template tags can modify template on fly.

Example

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.

context Module

Methods for context accessing

filter Module

Package provides template filters management

class lighty.templates.filter.FilterManager[source]

Bases: object

Class used for filters manipulations

apply(filter, value, args, arg_types, context)[source]

Apply filter to values

is_filter_exists(name)[source]

Check is filter exists

register(filter)[source]

Register filter in manager

loaders Module

Package provides template loaders

class lighty.templates.loaders.FSLoader(template_dirs)[source]

Bases: lighty.templates.loaders.TemplateLoader

Class provides methods for template managing

class lighty.templates.loaders.TemplateLoader[source]

Bases: object

Class fot managing templates

get_template(name)[source]

Get template by name

register(name, template)[source]

Add loaded or generated template

tag Module

Package provides template tags manager and base tags list

class lighty.templates.tag.TagManager[source]

Bases: object

Class used for tags manipulation

execute(name, token, context, block, template, loader)[source]

Execute tag

is_block_tag(name)[source]

Check is tag with specified name is block tag

is_lazy_tag(name)[source]

Check is tag with specified name is lazy tag Lazy tag means that it would be executed on template execution. But some tags required to be executed on template parsing time.

is_tag_exists(name)[source]

Check is tag exists

register(name, tag, is_block_tag=False, context_required=False, template_required=False, loader_required=False, is_lazy_tag=True)[source]

Register new tag

template Module

Module provides template two template classes:

  • Template
  • LazyTemplate
class lighty.templates.template.LazyTemplate(text=None, loader=<lighty.templates.loaders.TemplateLoader object at 0x2ef7110>, name='unnamed')[source]

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.

execute(context)[source]

Execute

parse(text)[source]

Parse template later

prepare()[source]

Prepare to execution

class lighty.templates.template.Template(text=None, loader=<lighty.templates.loaders.TemplateLoader object at 0x2ef7110>, name='unnamed')[source]

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(context={})[source]

Execute all commands on a specified context

Arguments:
context: dict contains varibles
Returns:
string contains the whole result
static filter(value)[source]

Parse the tamplte filter

parse(text)[source]

Parse template string and create appropriate command list into this template instance

partial(context, name='', key_args=())[source]

Execute all commands on a specified context and cache the result as another template ready for execution

Arguments:
context: dict contains variables
Returns:
another template contains the result

templatefilters Module

Package contains default template tags

lighty.templates.templatefilters.addslashes(value)[source]

Add a slashes to string

lighty.templates.templatefilters.capfirst(value)[source]

Capitalizes the first character in string

lighty.templates.templatefilters.date(value, format)[source]

Convert date into python format

lighty.templates.templatefilters.dictsort(value, key, order='')[source]

Sort dict

lighty.templates.templatefilters.first(value)[source]

Get first item from list

lighty.templates.templatefilters.floatformat(raw_value, format='0')[source]

Make pretty float representation

Lets:
a = ‘12.4’
Then:
>>> print floatformat(a)
12
>>> print floatformat(a, '2')
12.40
>>> print floatformat(a, '-2')
12.4
lighty.templates.templatefilters.floatround(raw_value, format='0')[source]

Round a float value according to math rules

Lets:
a = ‘12.45’
Then:
>>> print floatround(a)
12
>>> print floatround(a, '1')
12.5
lighty.templates.templatefilters.get(value, index)[source]

Get item with specified index

lighty.templates.templatefilters.join(value, joiner)[source]

Join list or items with joiner

>>> join([1, 2, 3], ' ')
'1 2 3'
lighty.templates.templatefilters.last(value)[source]

Get last item from list

lighty.templates.templatefilters.length(value)[source]

Return’s the length of the string, dict or list

lighty.templates.templatefilters.lower(value)[source]

Convert to lower case

lighty.templates.templatefilters.random(value)[source]

Get random item from list or dict

lighty.templates.templatefilters.sort(value, order='')[source]

Sort list

lighty.templates.templatefilters.stringformat(value, format)[source]

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

lighty.templates.templatefilters.sum(*args)[source]

Calculate the sum of all the values passed as args and

lighty.templates.templatefilters.upper(value)[source]

Convert to upper case

templatetags Module

Basic template tags library

class lighty.templates.templatetags.Forloop(var_name, values, block)[source]

Class for executing block in loop with a context update

lighty.templates.templatetags.block(token, block, template, loader)[source]

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>
lighty.templates.templatetags.exec_block(block, context)[source]

Helper function that can be used in block tags to execute inner template code on a specified context

lighty.templates.templatetags.exec_with_context(func, context={}, context_diff={})[source]

Execute function with context switching

lighty.templates.templatetags.extend(token, template, loader)[source]

Tag used to create tamplates iheritance. To get more information about templates inheritance see block().

lighty.templates.templatetags.find_command(command, template)[source]

Find command in commands list

lighty.templates.templatetags.for_tag(token, block, context)[source]

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>
lighty.templates.templatetags.get_parent_blocks(template)[source]

Get parent blocks

lighty.templates.templatetags.if_tag(token, block, context)[source]

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
lighty.templates.templatetags.include(token, context, loader)[source]

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>
lighty.templates.templatetags.replace_command(template, command, replacement)[source]

Search for command in commands list and replace it with a new one

lighty.templates.templatetags.spaceless(token, block, context)[source]

This tag removes unused spaces

Template:

{% spaceless %}
    Some
            text
{% endspaceless %}

will be rendered to:

Some text
lighty.templates.templatetags.with_tag(token, block, context)[source]

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 %}