Is it possible to import a Python module into a Jinja template so I can use its functions?
For example, I have a format.py file that contains methods for formatting dates and times. In a Jinja macro, can I do something like the following?
{% from 'dates/format.py' import timesince %}
{% macro time(mytime) %}
<a title="{{ mytime }}">{{ timesince(mytime) }}</a>
{% endmacro %}
Because format.py is not a template, the code above gives me this error:
UndefinedError: the template 'dates/format.py' (imported on line 2 in 'dates/macros.html') does not export the requested name 'timesince'
...but I was wondering if there was another way to achieve this.
Use the jinja2 {% include %} directive. This will include the content from the correct content-file. Show activity on this post. You can use the include statement.
Jinja is a web template engine for the Python programming language. It was created by Armin Ronacher and is licensed under a BSD License. Jinja is similar to the Django template engine but provides Python-like expressions while ensuring that the templates are evaluated in a sandbox.
Jinja is a template engine for Python. It is similar to the Django template engine. A template engine or template processor is a library designed to combine templates with a data model to produce documents.
Within the template, no, you cannot import python code.
The way to do this is to register the function as a jinja2 custom filter, like this:
In your python file:
from dates.format import timesince
environment = jinja2.Environment(whatever)
environment.filters['timesince'] = timesince
# render template here
In your template:
{% macro time(mytime) %}
<a title="{{ mytime }}">{{ mytime|timesince }}</a>
{% endmacro %}
Just pass the function into the template, like so
from dates.format import timesince
your_template.render(timesince)
and in the template, just call it like any other function,
{% macro time(mytime) %}
<a title="{{ mytime }}">{{ timesince(mytime) }}</a>
{% endmacro %}
Functions are first-class citizens in python, so you can pass them around just like anything else. You could even pass in a whole module if you wanted.
A template doesn't know import
, but you can teach it with the importlib
:
import importlib
my_template.render( imp0rt = importlib.import_module ) # can't use 'import', because it's reserved
(you can also name it "import"
by passing the argument with a dict
)
kwargs = { 'import' : importlib.import_module }
my_template.render( **kwargs )
then in the jinja-template, you can import any module:
{% set time = imp0rt( 'time' ) %}
{{ time.time() }}
You can export all of the symbols available in a module by providing the modules __dict__ as a parameter to the jinja template render method. The following will make available functions and types of __builtin__, inspect and types module to the template.
import __builtin__
import inspect
import types
env=RelEnvironment()
template = env.get_template(templatefile)
export_dict={}
export_dict.update(__builtin__.__dict__)
export_dict.update(types.__dict__)
export_dict.update(inspect.__dict__)
result=template.render(**export_dict)
Within template, to use a function of the exported modules similar to the following:
{%- for element in getmembers(object) -%}
{# Use the getmembers function from inspect module on an object #}
{% endfor %}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With