How to load jinja template directly from filesystem
Question:
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?
Answers:
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.
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')
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")
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+
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)
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?
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.
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')
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")
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+
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)