Jinja2 Explained in 5 Minutes!

Diva Dugar
codeburst
Published in
5 min readMar 16, 2018

--

(Part 4: Back-end Web Framework: Flask)

What is Jinja 2?

Jinja2 is a modern day templating language for Python developers. It was made after Django’s template. It is used to create HTML, XML or other markup formats that are returned to the user via an HTTP request. You can read more here.

How To Get Jinja 2

pip install jinja2easy_install jinja2

Why do we need Jinja 2?

  1. Sandboxed Execution: It provides a protected framework for automation of testing programs, whose behaviour is unknown and must be investigated.
  2. HTML Escaping: Jinja 2 has a powerful automatic HTML Escaping, which helps preventing Cross-site Scripting (XSS Attack). There are special characters like >,<,&, etc. which carry special meanings in the templates. So, if you want to use them as regular text in your documents then, replace them with entities. Not doing so might lead to XSS-Attack.
  3. Template Inheritance: This is the most important feature, which I will expand on to later in the post.

What are Templates?

Back in the days, servers used to have a collection of files, like HTML files, which were sent over as requested by clients. These were static data being sent over.

Now, in the modern web world, we have less of static data and more of dynamic data being requested from clients and therefore sent by the server. The web totally depends on what the client is asking for, and on which user is signing in and who is logging out. So, Jinja2 templating is being used.

A template contains variables which are replaced by the values which are passed in when the template is rendered. Variables are helpful with the dynamic data.

Structure of Flask App

/app
-/app.py
/templates
-/index.html
-/404.html

The structure of your application helps to keep your code organised and accessible. Flask expects the templates directory to be in the same folder as the module in which it was created. You can specify the location of the template_folder. Remember to keep your templates file in the templates folder.

app = Flask(__name__, template_folder='../pages/templates')

Delimiters

  • {%....%} are for statements
  • {{....}} are expressions used to print to template output
  • {#....#} are for comments which are not included in the template output
  • #....## are used as line statements

Write this file in app/templates/index.html:

<!DOCTYPE html>
<html>
<p>Hello {{ username }}</p>
</body>
</html>

This is a very simple HTML file. Variables are like the placeholders which store dynamic data or values. These values may be passed or provided as arguments in render_template() call. Rendering is a process of filling these placeholders with actual data. As HTML file is rendered, data is sent to a client.

Write this file in app/routes.py:

from flask import Flask, render_templateapp = Flask(__name__, template_folder=’’)@app.route(‘/user/<username>’)
def index(username):
return render_template(‘index.html’, username=username)
if __name__ == ‘__main__’:
app.run(debug=True)

So, now we render HTML by using render_template() . The syntax is:

flask.render_template(template_name_or_list,**content)

This renders a template from the templates folder with the given content.

  • template_name_or_list is the name of the template to be rendered or iterated.
  • ** means it is looking for keyword arguments.

Values can also be passed to the templates via the content dictionary. To print the value of variable, we use a{{ username }} .To access the variable’s attributes, we can either use {{ username.surname}} or {{ username['title'] }}.

Conditional Statement

So long we’ve seen only seen one of the many advantages of Jinja 2. To control the flow of the program, we create a structure which is controlled by conditional statements. {%....%} these are the placeholders from which all the conditions are executed.

This is the app/routes.py file

from flask import Flask, render_template

app = Flask(__name__)
@app.route(‘/’)
def index():
list_example = [‘Alvin’, ‘Simon’, ‘Theodore’]
return render_template(‘index1.html’, list_example=list_example)

if __name__ == ‘__main__’:
app.run(debug=True)

Next is the HTML file stored in app/templates/index.html:

<!DOCTYPE html>
<html>
<head>
<title>Conditions</title>
</head>
<body>
<ul>
{% for name in list_example %}
<li>{{ name }}</li>
{% endfor %}
</ul>

<ol>
{% for name in list_example %}
<li>{{ name }}</li>
{% endfor %}
</ol>

</body>
</html>

So, we use for loop to iterate over the list_example and print it with this placeholder{{ name }}. To end for loop use {%endfor%} and to end if loop, use {%endif%}.

**Template Inheritance**

Jinja 2 supports Template Inheritance, which is one of the most powerful and useful features of any template engine. It means one template can inherit from another template.

Nowadays, websites require the same layout for different pages. Almost every website has a navigation bar attached to its page. To not repeat the code, we use inheritance feature because it saves us a lot of time and also reduces work.

A base template contains the basic layout which is common to all the other templates, and it is from this base template we extend or derive the layout for other pages.

Structure of Template Inheritance

/app/app.py

from flask import Flask, render_template

app = Flask(__name__)

@app.route(‘/’)
def index():
return render_template(‘index.html’)
@app.errorhandler(404)
def page_not_found(e):
return render_template(‘404.html’), 404
if __name__ == ‘__main__’:
app.run(debug=True)

/app/templates/base.html

<! — “Parent Template” →
<!DOCTYPE html>
<html>
<head>
{% block head %}
<title>{% block title %}{% endblock %}</title>
{% endblock %}
</head>
<body>
{% block body %}{% endblock %}
</body>
</html>

Template Inheritance uses {% block %} tag to tell the template engine to override the common elements of your site via child templates. base.html is the parent template which is the basic layout and on which you can modify using the child templates, which is used to fill empty blocks with content. base.html is a general layout of the Web page.

/app/templates/index.html

<! — “Child Template” →
{% extends “base.html” %}
{% block title %} Index {% endblock %}
{% block head %}
{{ super() }}
{% endblock %}
{% block body %}
<h1>Hello World</h1>
<p>Welcome to my site.</p>
{% endblock %}

The {% extend %} must be the first tag in the child templates. This tag tells the template engine that this template extends from the parent template or ( base.html ). {% extend %} represents the inheritance characteristic of Jinja 2. So now the {% extend "base.html"%} first searches for the template mentioned and then the child template index.html overrides it with a different data.

/app/templates/404.html

{% extends ‘base.html’ %}{% block title %} Page Not Found {% endblock %}{% block body %}
<h1>404 Error :(</h1>
<p>What you were looking for is just not there.<p>
<a href=”{{ url_for(‘index’) }}”>go somewhere nice</a>
{% endblock %}

I’ve also added another child template to the parent template, to show that the layout doesn’t change. This is an error page. So, whenever the user gives an invalid path or web address which does not exist then, 404 Error will pop up. I’ve used an errorhandler() function, which is called when an error happens.

Thanks for reading! My previous post on Flask is here.
You can also give support here: https://
buymeacoffee.com/divadugar

--

--