Template language in Django

The template language in Django is used to reuse the HTML and CSS code. A typical HTML page consists of hundreds or even thousands of lines: it’s a lot of repetitive work. But what if you need to change a tag or a class of several similar elements?

If you’re working on a site, this little problem can totally spoil the evening. Yet there is a way to avoid unnecessary copy-pasting: you can use the power of Django Template Language (DTL).

DTL

DTL is a language that permits you to manipulate the elements of an HTML page on the server-side. Templates are files that comprise of special syntax constructions and HTML design.

These constructions permit you to modify the page content before sending it to the client. So templates assist you with customizing a page directly: for every user.

The work with DTL begins with four essential pillars: variables, control expressions, tags, and filters. All of that comes with the framework. You can likewise define your own filters and tags, however before you get to that, beginning with factors and control articulations.

Keep in mind, templates have tools for programming directly on the page, yet you ought not to overuse them: for that reason, views handlers are more appropriate.

If you just need the length of some expression and not simply the expression, you ought to calculate the length before sending it to a template. In any case, if you need both, DTL will prove to be useful.

Prepare a project

Create a Django project with any name you like and add the application blog in it. Define a simple handler to render a template in the blog/views.py module:

from django.views import View
from django.shortcuts import render

blog_name = "John Doe's blog"
post = {
    "text": "My first post",
    "theme": "Easy talk",
    "comments": [
        "My congratulations!!",
        "Looking forward to the second one",
    ],
}


class MainView(View):
    def get(self, request, *args, **kwargs):
        context = {"post": post, "blog_name": blog_name}
        return render(request, "blog/index.html", context=context)

Do not forget to add “blog” to your INSTALLED_APPS in the settings.py module, and then add this code to your urls.py module:

from blog.views import MainView
 
urlpatterns = [
    path("", MainView.as_view()),
]

just look through the content of the post and blog_name variables.

Finally, paste this template to the blog/templates/blog/index.html file:

<html>
  <body>
    <h2>{{ blog_name }}</h2>
    <div>{{ post.text }}</div>
  </body>
</html>

You can keep using this file later on, just replace its content when you need!

Variables

Variables are used to deliver the data to the templates. Usually, all data comes from the controller, but you can define your own variables right in the template, too.

Here is what you can pass from the Python code to the template:

  • primitive types like integers and strings
  • common Python structures such as dict, list, set, or tuple
  • functions with no extra arguments
  • an instance of a custom class

Actually, you can pass any Python object in templates, but for any other type, it makes no sense because you cannot use them properly.

To render the variable or its attributes, you should use a special syntax to distinguish DTL from HTML. Put the variable in double curly brackets {{ and }}:

<!-- Accessing a variable -->
<h2>{{ blog_name }}</h2>

If you want to access the attributes of the variable, use the dot operator:

<!-- Accessing the value of a dict by key -->
<div>{{ post.text }}</div>

It’s possible to call the variable’s method without extra arguments, the difference is that you don’t need round brackets after the call. If you want to capitalize on all words in the blog name, call the title method of a string variable {{ blog_name.title }}. Here is a nice simple example for you:

<h2>{{ blog_name.title }}</h2>

Conditions

With controlling statements, we can pick what we show or do on the page depending upon the conditions.

Much the same as in Python, branching in DTL comprises of if, elif, and else statements. Curly brackets with the percent sign {% and %} embrace them and the various tags: it differs tags from variables syntactically.

All branches should begin with {% if %} and end with {% endif %} statements.

Let’s return to our example: Make necessary changes accordingly. The content of the post represents itself with no issue. To hold the format of a page, and if there’s no topic, the header will be “No theme” also:

<html>
  <body>
    <h3>
      {% if post.theme %} Theme: {{ post.theme }}
      {% else %} No theme
      <!-- Without the closing tag the whole expression is not correct -->
      {% endif %}
    </h3>
    <a href="https://codedec.com/tutorials/launching-web-server-in-django/">How to make a post entry with Django</a>
  </body>
</html>

If you don’t have a variable at all when you get access to a value, it’s not a grave mistake. The rule is, if we do not pass a variable in the context, the value of this variable is by default None.

Be cautious if you want to access attributes and methods of None: this will cause an error.

Loops

Sometimes we don’t know how many items we’ve got in a list, but we still want to show all of them one by one on a page. Loops are helpful when you have to iterate over a lot of similar elements.

The template loops are similar to Python for expressions. Start one with {% for %} and end it with {% endfor %} statements.

For example, add a section to the blog which will show all the comments! Let’s render all comments to the post one after another:

<html>
  <body>
    {% for comment in post.comments %}
      <div>Comment #{{ forloop.counter }}: {{ comment }}</div>
    {% endfor %}
  </body>
</html>

To access the index of the element, we use {{ forloop.counter0 }} for zero-based iteration and {{ forloop.counter }} for one-based .

Conclusion

Let’s summarize! Templates provide tools to:

  • Pass variables to the HTML layout
  • Control the data you render
  • Iterate over multiple similar elements

Template language helps you work with the HTML layout and make your life as a developer much easier.