Getting Started with Creating Custom Templating System with Jinja2
Templating is an unavoidable part of modern dynamic web application design & development. If your system or application is serving HTML content to the user and you are not using any templating system then you’re probably doing something wrong. There are a lot of templating systems available nowadays and in the world of Python Jinja, to be specific Jinja2, is the best way to go.
If you are developing your own web application framework, tool or standalone system in Python then consider using Jinja2 for your project. Jinja2 is a standalone template engine. So, you can use it in any project without another heavy dependency. Jinja was inspired by the Django template engine. The template engine Django provides is really great but it also has some limitations and shortcomings. Further, you cannot easily use Django’s template engine without using it inside a Django project. Jinja came as our savior.
Who this Guide is for?
At the first glance you many be tempted to think that this guide is for template designers, but that’s not the case. This is for the custom templating system developers or for those developers that want to include a templating system in their application, library, framework, or tool.
In this series of guides I am going to cover how to create, integrate, and implement a custom templating system. We do not need to reinvent the wheel for that. We can use a modern template engine like Jinja2 and exploit its highly customizable behavior to reach our goal.
This is the first guide of the series and in this guide we are not going to do any customization. We just look at how to use Jinja2 APIs for integrating it with any projects.
Before You Begin
This is not a beginner guide. So, it is expected that you check the following list before you begin.
- You must have at least basic knowledge in Python along with the familiarity with Object Oriented Programming.
- You should have proper knowledge about template syntax of Django templates or Jinja2. If you do not have knowledge in them but have familiarity with Twig, you will feel at home.
- You should have Python 3 installed on your machine.
- You should have experience in working with command line on your system.
- Choose or create a directory where you want to keep your code for this guide.
- Create a file named jinja_beginning.py in your chosen directory.
- You can work inside a virtual environment if you like.
Installing Jinja2
For this guide the only external library we need is jinja2. Install it with the following command.
$ pip install jinja2
Any dependency of Jinja2 will automatically be installed.
Setting up the Template Directory
Templates are usually loaded by their file names. But we do not provide the full paths of the template file to the template engines. Instead, we pass a file name relative to a directory. Let's say that we want to keep our Jinja2 templates inside the templates directory inside our chosen directory. So, let's create a directory named templates inside our chosen directory.
Creating an Environment
Jinja needs an environment created for working with templates. Environment is the single source of truth (data) for templates. Later we provide more data to the template through the context at the time of rendering.
import jinja2
template_env = jinja2.Environment()
But we haven't told Jinja about how to find and load templates. Jinja is very flexible, you can load templates from the file system, strings, or customize it to load them from elsewhere, e.g. from a database or external servers. We need to provide Jinja with a loader class. We can create them or we can use any of the existing ones provided by Jinja. Jinja already solved the most common problems. We usually load templates from the file system and Jinja has a file system loader for that. Let's use it.
The file system loader needs the directory path where we are want to store the templates. Let's find the absolute path to the templates folder with the following code.
import os
templates_dir = os.path.join(os.getcwd(), 'templates')
Now let's pass the jinja2.FileSystemLoader class to the environment as a keyword argument.
import jinja2
import os
templates_dir = os.path.join(os.getcwd(), 'templates')
templates_dir
template_env = jinja2.Environment(
loader=jinja2.FileSystemLoader(templates_dir, encoding='utf-8', followlinks=False)
)
Notice that we passed the absolute path to FileSystemLoader as the first positional argument, and with the keyword argument encoding we specified the encoding we are going to use for our template files. followlinks=False asks the engine to not follow symlinks.
Creating a Template
Jinja does not care what file extension we use for template files. It just expects that we provide plain text files with whatever extension. We are going to use '.html' as the extension of our template files. So, let's create a file named person.html inside the templates directory.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title> {{name}}'s details </title>
</head>
<body>
<h1> {{name}}'s details </h2>
<b> Name: </b> {{ name }} <br />
<b> Email: </b> {{ email }} <br />
<b> Website: </b> {{ website }} <br />
<b> Github: </b> {{ github }} <br />
</body>
</html>
We need four context variables for this template that we are going to pass when we render with the template.
Loading and Rendering
Before we can use a template we need to load it with the help of environment.
import jinja2
import os
templates_dir = os.path.join(os.getcwd(), 'templates')
templates_dir
template_env = jinja2.Environment(
loader=jinja2.FileSystemLoader(templates_dir, encoding='utf-8', followlinks=False)
)
loaded_template = template_env.get_template("person.html")
result = loaded_template.render(name="Md. Sabuj Sarker", email="md.sabuj.sarker@gmail.com", website="http://sabuj.me", github="https://github.com/SabujXi")
print(result)
Running the code we get the following output:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title> Md. Sabuj Sarker's details </title>
</head>
<body>
<h1> Md. Sabuj Sarker's details </h2>
<b> Name: </b> Md. Sabuj Sarker <br />
<b> Email: </b> md.sabuj.sarker@gmail.com <br />
<b> Website: </b> http://sabuj.me <br />
<b> Github: </b> https://github.com/SabujXi <br />
</body>
</html>
Without going through any hassle of writing a lot of HTML code we have got HTML output with clean Python code. We did not think about string replacing, interpolation, evaluation or anything else. We pass pure Python objects to Jinja and it does the rest for us. Now we are capable of creating any number of HTML files without touching any HTML code—we can do it all in pure Python.
Conclusion
This guide is the foundation of all the guides in this series. Try to understand every bit of it and don't forget to practice as much as you can.
Recent Stories
Top DiscoverSDK Experts
Compare Products
Select up to three two products to compare by clicking on the compare icon () of each product.
{{compareToolModel.Error}}
{{CommentsModel.TotalCount}} Comments
Your Comment