I'd like to render a fused Jinja2 and Markdown page using a template, which looks like so:
{% block title %}{{ title }}{% endblock %}
# {{ title[0] }}
# {{ title[1] }}
## Introduction
I can get that above code to generate HTML fine, but as I am using this script for a custom authoring application, I'd like to be able to define master templates for each type of entry.
When I try to render the above page by extending a master template, template.html
:
{% extends 'template.html' %}
{% block title %}{{ title }}{% endblock %}
# {{ title[0] }}
# {{ title[1] }}
## Introduction
I get an error:
Traceback (most recent call last):
File "compiler.py", line 55, in <module>
template = Template(text).render(parser.vars)
File "/usr/lib/python2.7/site-packages/jinja2/environment.py", line 891, in render
return self.environment.handle_exception(exc_info, True)
File "<template>", line 1, in top-level template code
TypeError: no loader for this environment specified
You can see that the problematic line is template = Template(text).render(parser.vars)
.
Is there any way that I can render the above template code and be able to extend template.html
?
Jinja's renderer needs to know how to load template.html
, so you need to give the Environment
a template loader instance.
For example, assuming the files page.html
and template.html
are in the current directory:
from jinja import FileSystemLoader
from jinja.environment import Environment
env = Environment()
env.loader = FileSystemLoader('.')
tmpl = env.get_template('page.html')
print tmpl.render(parser.vars)
Updated - You can create a custom template loader, or use one of the existing classes defined in jinja2.loaders. For example, the DictLoader
would look up template.html
in a dict()
instance and treat the value as the template data. It should be straightforward to load your templates from just about anywhere (e.g. memcache, mysql, redis, a Python object, etc).
Example of using DictLoader
:
pages = ('template.html', 'page.html')
templates = dict((name, open(name, 'rb').read()) for name in pages)
env.loader = DictLoader(templates)
page.html
{% extends "template.html" %}