By Md. Sabuj Sarker | 12/14/2017 | General |Intermediate

Customizing the Jinja2 Environment

Customizing the Jinja2 Environment

Environment is the single source of truth in the world of Jinja2 template engine. This is the entry point of doing something or starting customizing in Jinja2. In this guide I will teach you how to customize the Jinja2 environment.

Before You Begin

As mentioned previously I want to remind you again that this is not a beginners' guide, neither a guide for template designers. It is a guide for template developers or template system developers. Don't forget to check the following list before you move forward.

  • Make sure that you have gone through the previous (the first one) guide in this series and practiced the code by your own hands.
  • Make sure that you have Python 3 installed on your system.
  • Make sure you have familiarity with Object Oriented Programming concepts in Python.
  • Make sure that you are comfortable working with command lines.

Preparing Working Environment

Choose or create a directory where you want to keep the python script files. Create a file called jinja2_env.py in that directory. Create a 'templates' folder where we want to keep our template files. Create a template file named person.html with the following content in it.

<!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> Age: </b> {{ age }} - {% if age > 30 %} he is an old man {% else %} he is still quite young {% endif %}

<b> Email: </b> {{ email }} <br />

<b> Website: </b> {{ website }} <br />

<b> Github: </b> {{ github }} <br />

</body>
</html>

Now put the following code in your python script file:

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", age=28, email="md.sabuj.sarker@gmail.com", website="http://sabuj.me", github="https://github.com/SabujXi")
print(result)

Execute the script with the following command:

$ python3 jinja2_env.py

You will see 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> Age: </b> 28 -  he is still quite young 

<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>

Now, let's move to the next step.

Note: You may use any IDE or code editor or plain text editor for writing your Python or template codes.

Replacing the Curly Braces

In our template we used '{%' to start if, else, endif and '%}' to end those tags. But, that may not be liked by everyone or you may have a different requirement. Also, you may have in a situation where your template designers are more familiar with '<% ' and %>. What can we do for that? No worries! In Jinja2 we can change that by customizing the Environment. To do that we need to provide appropriate arguments to the environment during instantiation. The following two keyword arguments are needed for the customization:

  • block_start_string
  • block_end_string

So, our code will look like the following:

import jinja2, os

templates_dir = os.path.join(os.getcwd(), 'templates')

template_env = jinja2.Environment(
   loader=jinja2.FileSystemLoader(templates_dir, encoding='utf-8', followlinks=False),
   block_start_string = '<%',
   block_end_string = '%>'
)

loaded_template = template_env.get_template("person.html")
result = loaded_template.render(name="Md. Sabuj Sarker", age=28, email="md.sabuj.sarker@gmail.com", website="http://sabuj.me", github="https://github.com/SabujXi")
print(result)

Run the script and you will see the following unexpected output. I have intentionally put ... to indicate that I am skipping the start and end content and focusing on the primary concern:

...
<b> Age: </b> 28 - {% if age > 30 %} he is an old man {% else %} he is still quite young {% endif %}
...

This is because, now Jinja2 does not recognize '{%' and '%}' as any special syntax. So, we need to replace them with '<%' and '%>'. Let's do that in our person.html file:

...
<b> Age: </b> {{ age }} - <% if age > 30 %> he is an old man <% else %> he is still quite young <% endif %>
...

Now run the script again to see the correct output we got before.

But, we are still using '{{' and '}}' for outputting values of variables in their places. Let's change them to '<|' and '|>'.

<!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> Age: </b> <| age |> - <% if age > 30 %> he is an old man <% else %> he is still quite young <% endif %>

<b> Email: </b> <| email |> <br />

<b> Website: </b> <| website |> <br />

<b> Github: </b> <| github |> <br />

</body>
</html>

And we also need to pass two special keyword argument to the Environment constructor as in the following code:

template_env = jinja2.Environment(
   loader=jinja2.FileSystemLoader(templates_dir, encoding='utf-8', followlinks=False),
   block_start_string = '<%',
   block_end_string = '%>',
   variable_start_string = '<|',
   variable_end_string = '|>'
)

Now, run the script again to see 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> Age: </b> 28 -  he is still quite young 

<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>

So, we still have the same output as we had at the very beginning, but we have different syntax according to our taste now.

More Customization

In the previous section I showed you only two syntax change. There are a lot of more parameters with which you can customize the template system and make it your own. A few of the parameters are listed below:

  • comment_start_string and comment_end_string
    We usually use {# and #} for commenting out something in our Jinja2 templates. You can change those by passing your expected comment start and end string to the Environment constructor.
  • trim_blocks
    This is a boolean value. It is False by default. You can set it to True if you want that the first newline after a block be removed, False otherwise.
  • extensions
    You can pass a list of extensions to extend Jinja further. We will discuss this in a later guide.
  • optimized
    Optimization in Jinja is enabled by default. Set it to False if you want to disable optimization.
  • autoescape
    This boolean parameter controls the escaping of HTML and XML

Look at the official documentation to find more information on other parameters that are not mentioned here.

Conclusion

Making a customized template system is fun but creating a template engine for the same purpose is not easy and is time consuming. Use Jinja2 to make your custom template system to your heart's content. Keep practicing and keep improving your own templating system.

By Md. Sabuj Sarker | 12/14/2017 | General

{{CommentsModel.TotalCount}} Comments

Your Comment

{{CommentsModel.Message}}

Recent Stories

Top DiscoverSDK Experts

User photo
3355
Ashton Torrence
Web and Windows developer
GUI | Web and 11 more
View Profile
User photo
3220
Mendy Bennett
Experienced with Ad network & Ad servers.
Mobile | Ad Networks and 1 more
View Profile
User photo
3060
Karen Fitzgerald
7 years in Cross-Platform development.
Mobile | Cross Platform Frameworks
View Profile
Show All
X

Compare Products

Select up to three two products to compare by clicking on the compare icon () of each product.

{{compareToolModel.Error}}

Now comparing:

{{product.ProductName | createSubstring:25}} X
Compare Now