178

The jinja API document at pocoo.org states:

The simplest way to configure Jinja2 to load templates for your application looks roughly like this:

from jinja2 import Environment, PackageLoader env = Environment(loader=PackageLoader('yourapplication', templates')) 

This will create a template environment with the default settings and a loader that looks up the templates in the templates folder inside the yourapplication python package.

As it turns out, this isn't so simple because you have to make/install a python package with your templates in it, which introduces a lot of needless complexity, especially if you have no intention of distributing your code.

I found these related questions about doing so, but the answers are vague and unsatisfying:

How can I load the template directly from the filesystem, not as a resource in a package?

5 Answers 5

220

Use a FileSystemLoader instead of a PackageLoader. Suppose there is a python file in the same directory as the template:

./index.py ./template.html 

This index.py will find the template and render it:

#!/usr/bin/python import jinja2 templateLoader = jinja2.FileSystemLoader(searchpath="./") templateEnv = jinja2.Environment(loader=templateLoader) TEMPLATE_FILE = "template.html" template = templateEnv.get_template(TEMPLATE_FILE) outputText = template.render() # this is where to put args to the template renderer print(outputText) 

In the introduction, the PackageLoader approach seems to be presented as the default, "simplest" method; however, there is also a section which discusses all the built-in loaders.

Sign up to request clarification or add additional context in comments.

4 Comments

Sort of ridiculous you can't load a template from a file in one line e.g. jinja2.load_template('template.html')
I always have a Wrapper that I just call Jinja2 in my applications where I put all this verbosity, then call it like: Jinja2.render(template_name, data)
Important security risk! You almost certainly want to call jinja2.Environment(loader=templateLoader, autoescape=True). Or see the api docs for more info. Just found out I ended up with a major XSS vulnerability from following this answer :/
Both links at top are broken.
152

A simpler way is to directly call the jinja2.Template constructor and use open to load the file:

from jinja2 import Template with open('template.html.jinja2') as file_: template = Template(file_.read()) template.render(name='John') 

2 Comments

Unfortunately this does not allow setting up custom filters. The template loading generates an error during initialization because the custom filter doesn't exist yet. And this way you only have access to the environment (to include the filter) after initialization.
This gives me Can't compile non template nodes on Python 3, likely because file_.read returns bytes instead of the expected str | Template ("expected" as in "expected according to my IDE").
55

Here is the one liner:

from jinja2 import Template with open('template_file.j2') as f: template = Template(f.read()) 

Then you can render the template on another line, or for all in one line:

with open('template_file.j2') as f: rendered = Template(f.read()).render(var="TEXT") 

7 Comments

Sadly this will break if there is template inheritance, as Jinja won't be able to find the referenced templates.
But luckily this is simple and enough if you don't use inheritance, and just wan't to send some simple email for example.. :)
The other major downside to this one liner is that you don't close the file. At worst, this leads to file corruption. Would highly recommend using a python context and making it two lines rather than one!
@NikhilShinday Failing to close a file that is open for reading (the default mode of open) will absolutely never lead to file corruption.
It's not clear to me how this adds anything over Cas's answer.
|
23

If using Python 3.4+ and Jinja2 - v2.11+ -- we can combine python's pathlib and Filesystem to simplify the flow

from pathlib import Path ... p = Path(__file__).parent.parent / 'templates' # sample relative path env = Environment( loader=FileSystemLoader(Path(p))) template = env.get_template('your_file.jinja2') 

I am not comfortable with using directly Template(file) since Jinja's template inheritance processing may not work well.

Pathlib support is only added in latest version of Jinja - v2.11+

2 Comments

Path(p) is redundant.
This is a neat solution for when you get your pathname on the command line, and it could be absolute or relative: use p = Path(sys.argv[1]), then FileSystemLoader(p.parent) and env.get_template(p.name). Works for both relative and absolute pathnames.
2
from jinja2 import Environment, select_autoescape, FileSystemLoader env = Environment(loader=FileSystemLoader( searchpath=folder_contain_list_html), autoescape=select_autoescape(['html', 'xml'])) template = env.get_template('file_name_detail_template') body_html = template.render(**args) send_email(body_html) 

1 Comment

Format your code, provide some context and explain why your answer is better than the accepted one.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.