Template engine Jinja2

In the previous video, we learned how to return HTML pages from Flask. We also learned that it’s not a good idea to mix HTML and Python code. Also, we started using Jinja2 template engine to separate HTML and Python code. In this video, we’ll learn more about Jinja2, how to pass data to templates, and how to use template inheritance.

What is a template engine?

A template engine is a library that helps us rapidly build web applications that are split into different parts. Templates are also enable us to reuse the same HTML code in multiple places making working with HTML much easier. The template engine replaces variables in a template file with actual values and then sends the resulting HTML file to the client.

In this project we are going to use Jinja2 template engine. Jinja2 is a template engine for Python. It is a part of the Flask framework, but it can also be used as a standalone library. Jinja2 is a modern and designer-friendly templating language for Python. It is fast, widely used, and easy to learn. It is also extensible and supports many features, such as template inheritance, filters, and macros. Jinja2 is a great choice for building web applications with Python.

Let’s look at an example.

Passing data to templates

In the previous video we created a template named index.html. This template contains a variable named name. The variable is replaced with the actual value at runtime. To pass the value to the template, we modified the hello_world function to pass the name of the user to the template from the query string. This is how we can pass data to templates. We can pass more than one variable to the template. To do this, we need to add more variables to the template and pass them to the render_template function. so let’s update our online store.

We are going to add the product list to the home page. To display the product list on the home page, we need to pass the list to the render_template function. Then, we can use a for loop in our template to iterate over the list and display the products.

Here the code will take the name of the product, thanks to the for loop, the code will go through the entire list and display all the products in the list.

In this example, we deliberately used the variable name product_list in the Python code and the name products in the template. While you are free to use any variable names you want, it’s generally a good idea to use consistent names in both the Python code and the template to avoid confusion. Using consistent names can make your code easier to read and understand, especially for other developers who may be working on the same project. ** show with mouse **

It’s common practice to gather all the data that needs to be displayed in the template before rendering the template.

While the store we’ve created so far is pretty basic, we’ll be adding more features and functionality in the future to make it more interesting and useful.

Don’t worry that we put the list of products directly in the hello_world function. However, in a real-world application, we would typically get the list of products from a database or other data source. In the next videos, we’ll learn how to retrieve data from a database and use it to generate dynamic content in our templates.

Creating base template

One of the most useful features of Jinja2 is template inheritance. Template inheritance allows us to reuse the same HTML code in multiple places. For example, we can create a base template that contains the common parts of all pages, such as the header and the footer. Then, we can create child templates that extend the base template and override the common parts with the page-specific content. This allows us to avoid duplicating the same code in multiple places.

We already have the templates folder and “index.html” file inside it. Let’s move some of the code from the “index.html” file to a new file named “base.html”. To do this, create a new file named “base.html” inside the templates folder. Then, I’m going to copy the code from the “index.html” file and paste it into the “base.html” file. Then, I’m replacing our title with a jinja2 block named title. This block could be overridden in child templates, but we put a default value here. Next, I’m going to replace all the content inside the body tag. First, I’ll put a header tag, and add a stub for the header. Then I’ll add a main tag, and add a block named content. This block should be overridden in child templates. Finally, I’ll add a footer tag, and add a stub for the footer.

This code contains three blocks: head, body, and content. Blocks are used to define sections of a template that can be overridden in child templates. Blocks are defined using the following syntax: {% block block_name %}{% endblock %}. The block_name is the name of the block. The block_name can be any valid Python identifier. The block_name is used to identify the block.

Creating child template for home page

Now, let’s update the “index.html” file to extend the “base.html” template. Let’s put the extends directive at the top of the file. The extends directive tells Jinja2 that this template extends the “base.html” template. Then, let’s remove parts of the file which are already in the “base.html” template. We can remove…, and the h1 tag with the title. The rest of the code should be moved to the content block.

Let’s look at the result. Nothing changed. But now, we can add more pages to our website and reuse the same code in multiple places. It’s a good practice to follow the DRY principle. DRY stands for “Don’t Repeat Yourself”. It means that we should avoid duplicating the same code in multiple places. Instead, we should create reusable code and reuse it in multiple places. This makes our code easier to maintain and update.

Creating other pages

Similarly, you can create templates for other pages. For example, you can create a template for the about page. To do this, create a new file named about.html inside the templates folder. Then, I’m going to add the extends directive again. Then, I’m going to override the content block, and put something like this inside it.

Rendering templates

Now we have to tell Flask that we want to render the “about.html” template when the user visits the “/about” page. To do this, we need to create a new route for the “/about” page. Let’s add a new handle for that.

Let’s check if it works. It works. You can see that the content of the “about.html” template is displayed on the screen.

Congratulations! You’ve learned how to use Jinja2 template engine to create templates and pass data to them. You’ve also learned how to use template inheritance to reuse the same HTML code in multiple places. And now our online store has two pages: the home page and the about page.