Skip to main content

Build Status License Language

Scrippy, my scrangourou friend

scrippy_template

Simplified management of template files for the Scrippy framework.

Prerequisites

  • Python >= 3.11

Python modules

List of required modules

The modules listed below will be automatically installed.

  • jinja2

Installation

Manual

git clone https://codeberg.org/scrippy/scrippy-template.git
cd scrippy-template
python -m pip install -r requirements.txt
make install

With pip

pip install scrippy-template

Usage

This module allows document generation from template files using the Jinja2 rendering engine.

Loading and rendering a template file

The template.Renderer object is instantiated with:

  • base_path: the directory in which template files are searched for,
  • template_filename: the name of the template file, relative to base_path.

By convention, the template files used by the Scrippy framework are stored in the directory defined by the env.templatedir configuration parameter (see the configuration of the Scrippy framework in the relevant documentation).

The template file is checked as soon as it is loaded: a missing or unreadable template file, or a template file with a syntax error, raises a ScrippyTemplateError at instantiation.

The Renderer.render(params) method returns the rendering of the template file. The variables MUST be supplied to the template file as a dictionary named params, and are accessed from the template file as {{params.<variable>}}.

The template file is compiled at each rendering: a change made to the template file after it has been loaded is taken into account.

The Renderer.load(base_path, template_filename) method allows the same Renderer object to load another template file, possibly from another directory. The previously loaded template file is replaced.

from scrippy_template import template

renderer = template.Renderer("/var/scrippy/templates", "dead_parrot.j2")
print(renderer.render({"user": "Harry Fink"}))

renderer.load("/var/scrippy/other_templates", "cheese_shop.j2")
print(renderer.render({"cheese": "Red Leicester"}))

Undefined variables

Any variable used by the template file MUST be present in the params dictionary: an undefined variable raises a ScrippyTemplateError at rendering.

Optional variables must be explicitly handled in the template file, either with the is defined test or with the default filter:

Hello {{params.user}}{% if params.title is defined %} ({{params.title}}){% endif %}
Sent by {{params.sender | default("Scrippy")}}

HTML/XML escaping

Variables are automatically escaped only in template files whose name ends with one of the following extensions: .html, .htm, .xml, .html.j2, .htm.j2, .xml.j2.

All other template files (.j2, .txt...) are rendered without any escaping.

With the template file report.html.j2:

<p>{{params.msg}}</p>

and params = {"msg": "<b>Spam & eggs</b>"}, the rendering is:

<p>&lt;b&gt;Spam &amp; eggs&lt;/b&gt;</p>

Jinja2 environment

The Jinja2 environment is accessible through the env attribute of the template.Renderer object. It is created at instantiation and kept when another template file is loaded with Renderer.load().

Changes made to the environment (filters, globals, options...) are taken into account at the next rendering:

renderer = template.Renderer("/var/scrippy/templates", "shout.j2")  # {{params.msg | shout}}
renderer.env.filters["shout"] = str.upper
print(renderer.render({"msg": "Spam, spam, spam"}))  # SPAM, SPAM, SPAM

Errors

All errors raise a scrippy_template.ScrippyTemplateError:

Error Raised by Message
Missing template file Renderer(), Renderer.load(), Renderer.render() Template not found: <base_path>/<template_filename>
Syntax error, unknown filter Renderer(), Renderer.load(), Renderer.render() Template syntax error: <base_path>/<template_filename> (line <n>): <message>
Undefined variable Renderer.render() Undefined variable: <message>
Any other error Renderer(), Renderer.load(), Renderer.render() Unexpected error: [<exception class>] <message>
from scrippy_template import template, ScrippyTemplateError

try:
  renderer = template.Renderer("/var/scrippy/templates", "dead_parrot.j2")
  print(renderer.render(params))
except ScrippyTemplateError as err:
  print(err)

Simple template file

With the following template file named dead_parrot.j2 located in the directory /var/scrippy/templates:

Hello {{params.user}}

You received this email because you are a member of the functional administrators of {{params.app}}.

The {{params.script}} script execution on {{params.date}} ended with the following error code:
- {{params.error.code}}: {{params.error.msg}}

--
Regards.
{{params.sender}}

The template file can be used as follows:

import datetime
from scrippy_template import template

params = {"user": "Harry Fink",
          "app": "Flying Circus",
          "script": "dead_parrot.py",
          "date": datetime.datetime.now().strftime("%Y/%m/%d"),
          "error": {"code": 42,
                    "msg": "It's not pinin'! It's passed on! This parrot is no more!"},
          "sender": "Luiggi Vercotti"}

base_path = "/var/scrippy/templates"
template_file = "dead_parrot.j2"
renderer = template.Renderer(base_path, template_file)

print(renderer.render(params))

The rendering will be:

Hello Harry Fink

You received this email because you are a member of the functional administrators of Flying Circus.

The dead_parrot.py script execution on 2019/09/15 ended with the following error code:
- 42: It's not pinin'! It's passed on! This parrot is no more!

--
Regards.
Luiggi Vercotti

Template file with control structures

params = {"user": "Harry Fink",
          "app": "Flying Circus",
          "script": "dead_parrot.py",
          "date": datetime.datetime.now().strftime("%Y/%m/%d"),
          "num_errors": 42,
          "sender": "Luiggi Vercotti"}
Hello {{params.user}}

You received this email because you are a member of the functional administrators of {{params.app}}.

The {{params.script}} script execution on {{params.date}} ended
{%- if params.num_errors == 0 %} without error.
{%- else %} with {{params.num_errors}} error(s).
{%- endif %}

--
Regards.
{{params.sender}}

The rendering will be:

Hello Harry Fink

You received this email because you are a member of the functional administrators of Flying Circus.

The dead_parrot.py script execution on 2019/09/15 ended with 42 error(s).

--
Regards.
Luiggi Vercotti

Template file with loop

params = {"user": "Harry Fink",
          "app": "Flying Circus",
          "script": "dead_parrot.py",
          "date": datetime.datetime.now().strftime("%Y/%m/%d"),
          "errors": [{"code": 2, "msg": "It's not pinin'! It's passed on! This parrot is no more!"},
                     {"code": 3, "msg": "Ohh! The cat's eaten it."}],
          "sender": "Luiggi Vercotti"}
Hello {{params.user}}

You received this email because you are a member of the functional administrators of {{params.app}}.

The {{params.script}} script execution on {{params.date}} ended with the following errors:
{% for error in params.errors -%}
- {{error.code}}: {{error.msg}}
{% endfor %}
--
Regards.
{{params.sender}}

The rendering will be:

Hello Harry Fink

You received this email because you are a member of the functional administrators of Flying Circus.

The dead_parrot.py script execution on 2019/09/15 ended with the following errors:
- 2: It's not pinin'! It's passed on! This parrot is no more!
- 3: Ohh! The cat's eaten it.

--
Regards.
Luiggi Vercotti

Metadata

Release files for scrippy-template 2.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for scrippy-template 2.0.0
File Size Uploaded
scrippy_template-2.0.0.tar.gz 10.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for scrippy-template 2.0.0
File Interpreter ABI Platform
scrippy_template-2.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 17.7 kB

Release files / scrippy_template-2.0.0.tar.gz

Download URL scrippy_template-2.0.0.tar.gz
Size 10.7 kB
Tags Source
SHA-256 checksum
How to use checksums
9471147902a5d783e2f31193ba530cd4c22979321ca34135d0afee588bdad129
BLAKE2b-256 checksum
How to use checksums
64a24f033612a4064b18c80be8cdb2757af16cdd6006f62199cc3f1d9513554f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.17

Release files / scrippy_template-2.0.0-py3-none-any.whl

Download URL scrippy_template-2.0.0-py3-none-any.whl
Size 7.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7a174261183530bdc5af9dd4107015e7248d5b6117be1c8ad54dba4129b75cf5
BLAKE2b-256 checksum
How to use checksums
4f8aa2a95e45ba4005bef8204334fab1cc1a60f44dfb5758a4b7118a530ac5be
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.17

Release history Release notifications | RSS feed

2.0.1

2 release files

This release

2.0.0 This release

2 release files

1.1.88

2 release files

1.1.87

2 release files

1.1.84

2 release files

1.1.83

2 release files

1.1.82

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page