Using Piglet from a python module

Creating template objects

You can create template objects directly from strings:

from piglet import HTMLTemplate
tmpl = HTMLTemplate('<p>Hello $name</p>')
# Returns '<p>Hello Arthur</p>'
tmpl.render({'name':  'Arthur'})

# Returns 'Hello <Marvin>'
TextTemplate('Hello <$name>').render({'name':  'Marvin'})

Creating a template loader

Most of the time it’s better to use a template loader. The template loader class handles loading templates from files and caching compiled templates:

from piglet import TemplateLoader

loader = TemplateLoader(['./templates/'])
template = loader.load('mytemplate.html')
print(template.render({'greeting': 'Hello!'})

Fully customized example:

from piglet import TemplateLoader, HTMLTemplate, TextTemplate

def get_translations():
    from gettext import GNUTranslations
    return GNUTranslations(somefile)

loader = TemplateLoader(search_path=['my-templates'],

                        # Reload templates when the source file changes
                        auto_reload=True,

                        # Encoding to assume when loading template files
                        default_encoding='UTF-8',

                        # Map of file extension to template class
                        extension_map={'.txt': TextTemplate,
                                       '.html': HTMLTemplate},

                        # Fallback template class to use
                        template_cls=HTMLTemplate,

                        # Factory function returning a
                        # ``gettext.translations`` object
                        translations_factory=get_translations,

                        # Template cache directory
                        cache_dir='/home/myuser/.cache/piglet/',

                        # Enable loading templates by absolute pathname
                        allow_absolute_paths=True)

Loading and rendering templates

Use piglet.loader.TemplateLoader.load() to load a template object from a file:

t = loader.load('index.html')
context = {}
print(t.render(context))

You can specify the template class or file encoding to be used when loading an individual template:

t = loader.load('readme.txt', encoding='UTF-8', template_cls=TextTemplate)

Template objects can also generate rendered content as an iterator. This can be useful for streaming large templated responses:

t = loader.load('index.html')
for chunk in t(context):
    print(chunk)

The template search path

The first argument to piglet.loader.TemplateLoader is the search path, a list of directories to search for template files.

When loading a template file via the loader, the first directory in the search path that contains a matching file is used.

If you are loading a template from another template (eg via py:extends) the template will be searched for on the configured search_path as normal.

If the referenced path starts with /, piglet will look for the template starting from the top level of each configured search directory.

If the referenced path starts with ./ or ../, piglet will look for the template relative to the current template’s directory first, and only consider other search_path directories if it is not found.

Otherwise piglet will look for the template across all configured search_path directories.

Given search_path=['a', 'b']:

Current template path

Requested path

Search order

a/index.html

layout.html

a/layout.html, b/layout.html

b/index.html

layout.html

a/layout.html, b/layout.html

b/subdir/index.html

layout.html

a/subdir/layout.html, b/subdir/layout.html

b/subdir/index.html

./layout.html

b/subdir/layout.html, a/subdir/layout.html

b/subdir/index.html

../layout.html

b/layout.html

b/subdir/index.html

/layout.html

b/layout.html, a/layout.html

Absolute paths

By default Piglet will not load templates from locations not configured in the search path.

You can override this by setting allow_absolute_paths=True

from piglet import TemplateLoader

loader = TemplateLoader(['my-templates'], allow_absolute_paths=True)
loader.load('/some/other/directory/index.html')