Python 3 - Template strings instead of external template engine

I don’t know about you, but there is only one thing where I use templates on the backend side.

Emails.

Usually, when people need to render HTML template, they install Jinja2 or other template engines.

The case is that it’s not always required.

If you have a template where you need to put some data, you don’t need an external template engine. When you need to do something with this data, you don’t need to do that inside a template using Jinja2 filters.

When I need to send an email, I have a ready template generated by some library for e-mails or external service. What I need to do is to insert the data and send it.

Python 3 has Template strings which can help here.

Let’s create a simple mixin.

import os

from string import Template


class TemplatesMixin:
    TEMPLATES_DIR = None

    def _read_template(self, template_path):
        with open(os.path.join(self.TEMPLATES_DIR, template_path)) as template:
            return template.read()

    def render(self, template_path, **kwargs):
        return Template(
            self._read_template(template_path)
        ).substitute(**kwargs)

As you can see, it reads the template and uses Template.substitute to insert the data. That’s all.

Example template:

<html>
  <head></head>
  <body>
    Hi $name
  </body>
</html>

Let’s say it’s stored in templates/emails/welcome.html.

First, specify somewhere (settings.py?) where you store the templates. Something like this:

from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent
TEMPLATES_DIR = BASE_DIR.joinpath('templates')

Now, I can use my mixin.


class SendEmail(TemplatesMixin):
    TEMPLATES_DIR = settings.TEMPLATES_DIR

    def post(self, request):
        # prepare some data

        email_body = self.render(
            'emails/welcome.html',
            name='eshlox',  # the data
        )

        # send an email, use email_body

You have to specify template path and params and the template is ready for sending.

No need for an external library. Modify your data using Python. Works for me ;-)