Minimal, fast templates for Python
Project description
Nano Templates
Minimal, fast, non-evaluating text templates for Python.
Install
TODO:
Example
import nano_template as nt
template = nt.parse("Hello, {{ you }}!")
print(template.render({"you": "World"})) # Hello, World!
About
Nano Template is a small text templating engine, written as a Python C extension, with syntax familiar to anyone who's used Jinja/Minijinja, Django templates or Liquid.
Unlike those popular template engines, Nano Template forces you to keep application logic out of template text by implementing a reduced feature set. In this scenario, template authors and application developer are likely to be the same person (or team of people).
Syntax
[!NOTE] In Nano templates, there are no filters or tests, no relational or membership operators, and we don't have for loop helpers or
{% break %}and{% continue %}.Instead, you should process your data in Python before rendering a template, or use Minijinja.
Available tags are
{% if %},{% elif %},{% else %}and{% for %}.
Variables
<div>{{ some.variable }}</div>
<p>{{ other["variable with spaces or special characters"] }}</p>
Conditions
{% if some.variable %}
more markup
{% elif another.variable %}
alternative markup
{% else %}
default markup
{% endif %}
Loops
{% for x in y %}
more markup with {{ x }}
{% else %}
default markup (y was empty or not iterable)
{% endfor %}
Logical operators
Logical operators and, or and not use Python truthiness and precedence rules, and terms can be grouped with parentheses.
{% if not a and b %}
markup with {{ b }} and {{ c }}.
{% endif %}
Logical and and or have last value semantics.
Hello, {{ user.name or "guest" }}!
Strings
String literals and quoted variable path segments can use single or double quotes, and allow JSON-style escape sequences.
{{ greeting or "Hi \uD83D\uDE00!" }}
Output:
Hi 😀!
Whitespace control
Control whitespace before and after markup delimiters with - and ~. ~ will remove newlines but retain space and tab characters. - strips all whitespace.
<ul>
{% for x in y ~%}
<li>{{ x }}</li>
{% endfor -%}
</ul>
API
render
render(source, data) is a convenience function that parses and immediately renders a template to a string. Use this for testing or when you know you'll be rendering the template just the once.
import nano_template as nt
print(nt.render("Hello, {{ you }}!", {"you", "World"}))
render also accepts serializer and undefined keyword arguments.
parse
parse(source) parses template text and returns an instance of Template for later rendering with the render(self, data) method.
import nano_template as nt
template = nt.parse("Hello, {{ you }}!")
print(template.render({"you": "World"})) # Hello, World!
print(template.render({"you": "Sue"})) # Hello, Sue!
parse also accepts serializer and undefined keyword arguments.
Serializing objects
By default, when outputting an object with {{ and }}, lists, dictionaries and tuples are rendered in JSON format. For all other objects we render the result of str(obj).
You can change this behavior by passing a callable to parse or render as the serializer keyword argument. The callable should accept an object and return its string representation suitable for output.
This example shows how one might define a serializer that can dump data classes with json.dumps.
import json
from dataclasses import asdict
from dataclasses import dataclass
from dataclasses import is_dataclass
import nano_template as nt
@dataclass
class SomeData:
foo: str
bar: int
def json_default(obj: object) -> object:
if is_dataclass(obj) and not isinstance(obj, type):
return asdict(obj)
raise TypeError(f"Object of type {obj.__class__.__name__} is not JSON serializable")
def my_serializer(obj: object) -> str:
return (
json.dumps(obj, default=json_default)
if isinstance(obj, (list, dict, tuple))
else str(obj)
)
template = nt.parse("{{ some_object }}", serializer=my_serializer)
data = {"some_object": [SomeData("hello", 42)]}
print(template.render(data)) # [{"foo": "hello", "bar": 42}]
Undefined variables
When a template variable or property can't be resolved, an instance of the undefined type is used instead. That is, an instance of nano_template.Undefined or a subclass of it.
The default undefined type renders nothing when output, evaluates to False when tested for truthiness and is an empty iterable when looped over. You can pass an alternative undefined type as the undefined keyword argument to parse or render to change this behavior.
Here we use the built-in StrictUndefined.
import nano_template as nt
t = nt.parse("{{ foo.nosuchthing }}", undefined=nt.StrictUndefined)
print(t.render({"foo": {}}))
# nano_template._exceptions.UndefinedVariableError: 'foo.nosuchthing' is undefined
# -> '{{ foo.nosuchthing }}':1:3
# |
# 1 | {{ foo.nosuchthing }}
# | ^^^ 'foo.nosuchthing' is undefined
Or you can implement you own.
from typing import Iterator
import nano_template as nt
class MyUndefined(nt.Undefined):
def __str__(self) -> str:
return "<MISSING>"
def __bool__(self) -> bool:
return False
def __iter__(self) -> Iterator[object]:
yield from ()
t = nt.parse("{{ foo.nosuchthing }}", undefined=MyUndefined)
print(t.render({"foo": {}})) # <MISSING>
Preliminary benchmark
TODO: move this
$ python scripts/benchmark.py
(001) Best of 5 rounds with 10000 iterations per round.
parse ext : best = 0.092188s | avg = 0.092236s
parse pure : best = 2.408759s | avg = 2.416534s
parse and render ext : best = 0.159726s | avg = 0.159882s
parse and render pure : best = 2.816334s | avg = 2.822223s
just render ext : best = 0.062731s | avg = 0.062923s
just render pure : best = 0.308758s | avg = 0.309301s
(002) Best of 5 rounds with 1000000 iterations per round.
render template : best = 0.413830s | avg = 0.419547s
format string : best = 0.375050s | avg = 0.375237s
Contributing
TODO: move this
ABI 3 Audit
Note that abi3audit ignores target ABI version when auditing .so files.
- Build a wheel locally with
python setup.py bdist_wheel - Run
abi3audit dist/<NAME>.whl --verbose
Example successful output:
[17:55:59] 💁 nano_template-0.1.0-cp39-abi3-linux_x86_64.whl: 1 extensions scanned; 0 ABI version mismatches and 0 ABI violations found
License
nano-template is distributed under the terms of the MIT license.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nano_template-0.1.0.tar.gz.
File metadata
- Download URL: nano_template-0.1.0.tar.gz
- Upload date:
- Size: 44.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1827b257ee6fbecf49abeb84501c350fc343a7c08171e18b00b2f642dcbb2476
|
|
| MD5 |
4ed079935c6dcfe70bf18736e6e1c0d5
|
|
| BLAKE2b-256 |
d49db270d4af33f3632ad080357a4644cd3e14503539377bb7dbbb20bb147aea
|
File details
Details for the file nano_template-0.1.0-cp314-cp314t-win_arm64.whl.
File metadata
- Download URL: nano_template-0.1.0-cp314-cp314t-win_arm64.whl
- Upload date:
- Size: 34.3 kB
- Tags: CPython 3.14t, Windows ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
923bde117904a864dea452ba42e2587a6a7b42766add37cac12d647a6a56a147
|
|
| MD5 |
a19c747018b77f9fb742378b0c34c52d
|
|
| BLAKE2b-256 |
e911705463982ffbec69eb6f34caa39b752d8d8654cfdceddfdea58cfcf2f87f
|
File details
Details for the file nano_template-0.1.0-cp314-cp314t-win_amd64.whl.
File metadata
- Download URL: nano_template-0.1.0-cp314-cp314t-win_amd64.whl
- Upload date:
- Size: 36.7 kB
- Tags: CPython 3.14t, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
de4e690fd4fc7331c7774901b7896e505e15e3119403c4b9dade51266631e47f
|
|
| MD5 |
b45993abe6effcfceed20d2769e97f20
|
|
| BLAKE2b-256 |
8cdf24569129c556d36ba642d8551311bbca6bf5176b0184d5e7e48fad544403
|
File details
Details for the file nano_template-0.1.0-cp314-cp314t-win32.whl.
File metadata
- Download URL: nano_template-0.1.0-cp314-cp314t-win32.whl
- Upload date:
- Size: 33.8 kB
- Tags: CPython 3.14t, Windows x86
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a7c31238552ca4dc6a24fe768c450e07f4c3d37fd32528394a488c068398f029
|
|
| MD5 |
26d82c4f7851204a6bb504aba676bfc8
|
|
| BLAKE2b-256 |
8f653313e6aace68974daa5a2c17ab8bf32071c2dd47284c31a06935439c0c7d
|
File details
Details for the file nano_template-0.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: nano_template-0.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 151.1 kB
- Tags: CPython 3.14t, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7a096a228eb32119fa132343915ee4802e689f4690547fdbe5c5d85f37289c41
|
|
| MD5 |
a55df8a55debdad728fd8c1a142bc286
|
|
| BLAKE2b-256 |
7044c6e023d0dd78d348e1abf009c7ac51a01acce2efb4a6eee3ca16058fc9d1
|
File details
Details for the file nano_template-0.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: nano_template-0.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 152.5 kB
- Tags: CPython 3.14t, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3610a921925184008ea0801e1757b2dc7b63cf3c8f3f503e7fc12d3ec529c74c
|
|
| MD5 |
c7b0f671d60e62f0afdd944f9fd5ff13
|
|
| BLAKE2b-256 |
b03777e40d51d55aad5d59046021d39cb5515ff9af507c7149b7f633adcc220c
|
File details
Details for the file nano_template-0.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: nano_template-0.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 153.8 kB
- Tags: CPython 3.14t, manylinux: glibc 2.17+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
58a50940f66cd9057eb7a1ecd02694b7332d15f4be258cd1a5a4956d5552d4dd
|
|
| MD5 |
aca619e8b9e9610de1d1a1e7a674fdf6
|
|
| BLAKE2b-256 |
b11c2d1640039543bcd90d3db7f3117f766b237f8814ebf34a96d42b8e6621a3
|
File details
Details for the file nano_template-0.1.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.
File metadata
- Download URL: nano_template-0.1.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
- Upload date:
- Size: 150.7 kB
- Tags: CPython 3.14t, manylinux: glibc 2.28+ x86-64, manylinux: glibc 2.5+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
02ae4440ba7a5730fd108657d94da350b41f6cd7367b8d421da9fca6a71ea920
|
|
| MD5 |
58859bda6fcb8e08f1498e5d2b6c2817
|
|
| BLAKE2b-256 |
39d93e5cbe0b618439b2874a2b7026620ba38274e27ad5fefc242b01ed7d949e
|
File details
Details for the file nano_template-0.1.0-cp314-cp314t-macosx_11_0_arm64.whl.
File metadata
- Download URL: nano_template-0.1.0-cp314-cp314t-macosx_11_0_arm64.whl
- Upload date:
- Size: 34.7 kB
- Tags: CPython 3.14t, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4f74beb46f3845cd84adb6635193bd8e47fa64d3d87a7b758e9f2fb32fb24b34
|
|
| MD5 |
cc7e089f61b572786e44780ff81cfe96
|
|
| BLAKE2b-256 |
76b6b9794a7a253d409a5687c02f468ed709d66ecd1cb8674ec73214884b5426
|
File details
Details for the file nano_template-0.1.0-cp314-cp314t-macosx_10_15_x86_64.whl.
File metadata
- Download URL: nano_template-0.1.0-cp314-cp314t-macosx_10_15_x86_64.whl
- Upload date:
- Size: 34.7 kB
- Tags: CPython 3.14t, macOS 10.15+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
986cd80c5d57a7a832c1f5f000a70ec6254c8141bfa32d2a94ecc555df2bc89b
|
|
| MD5 |
62d99bd620d17556e4a76feaf7e9534e
|
|
| BLAKE2b-256 |
687d16e36a07c267c9c293effe8c50d6e7a196e0ede505cf259f846e979d9bd0
|
File details
Details for the file nano_template-0.1.0-cp39-abi3-win_arm64.whl.
File metadata
- Download URL: nano_template-0.1.0-cp39-abi3-win_arm64.whl
- Upload date:
- Size: 32.7 kB
- Tags: CPython 3.9+, Windows ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2fce902365bc262519a573727444c572dae3b818573e6a7dc07d824ca5fa3c22
|
|
| MD5 |
a2bfbc8f3ff3ac66c3d11ca5cce083ad
|
|
| BLAKE2b-256 |
847fdbf902862fd650c5451bf2d3bf62d36be0e8c5762599b3818074734f9067
|
File details
Details for the file nano_template-0.1.0-cp39-abi3-win_amd64.whl.
File metadata
- Download URL: nano_template-0.1.0-cp39-abi3-win_amd64.whl
- Upload date:
- Size: 34.2 kB
- Tags: CPython 3.9+, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0b61a9019230605fd0011d739186ace4c51aa61e743638b4670fd4ed081bd8ef
|
|
| MD5 |
f0db95305ab05ea5c1c0d3561ff98ce7
|
|
| BLAKE2b-256 |
c55c9cedf5fdd76ac5f857587e70920939c16e2b8aec2fd16381e602efea3999
|
File details
Details for the file nano_template-0.1.0-cp39-abi3-win32.whl.
File metadata
- Download URL: nano_template-0.1.0-cp39-abi3-win32.whl
- Upload date:
- Size: 31.3 kB
- Tags: CPython 3.9+, Windows x86
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c7606e21cf6ff68aacdc18c70cd6e13a56d7fb62a2c370a3e6c5da600f861215
|
|
| MD5 |
24d8f950a1f6a07b057253804e17c94f
|
|
| BLAKE2b-256 |
6c266613c5cc5317118ea612164f8e5f0f4d8db5c98d4ef8d442bebdc7bc49cd
|
File details
Details for the file nano_template-0.1.0-cp39-abi3-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: nano_template-0.1.0-cp39-abi3-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 108.9 kB
- Tags: CPython 3.9+, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0adb8c09af87f5033eed01f16a76837cea7179be7f9a0bc1376fb6067c5c2699
|
|
| MD5 |
bac97f5a174109422334164126af7371
|
|
| BLAKE2b-256 |
5b8e65520242707e5960b85afffcc65f79cf1c88c28416eab10292b73668c7d3
|
File details
Details for the file nano_template-0.1.0-cp39-abi3-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: nano_template-0.1.0-cp39-abi3-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 109.7 kB
- Tags: CPython 3.9+, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0512c531d2347e55cb8c0cddb554ee763bdb2f89987e88c5267f4aff8feafe95
|
|
| MD5 |
4e3d97d1833f756f8d1d0e57c89a373c
|
|
| BLAKE2b-256 |
7beff9b4f2a3545752b362fe251275872289c9f8e6d8f3eebbb6f9eeeb81a993
|
File details
Details for the file nano_template-0.1.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: nano_template-0.1.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 112.5 kB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bbf1776088433655fd874c0e6f8b6cce1b864592100cdb501101d9971108a4b6
|
|
| MD5 |
c0ccaa4f693f8aff35667bc8da4ca195
|
|
| BLAKE2b-256 |
59f0972ab73662ac8f95b7c737adc42cd2ac6c4d272b6836c522a5d08100fb77
|
File details
Details for the file nano_template-0.1.0-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.
File metadata
- Download URL: nano_template-0.1.0-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
- Upload date:
- Size: 110.7 kB
- Tags: CPython 3.9+, manylinux: glibc 2.28+ x86-64, manylinux: glibc 2.5+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c9f40a76a43365c867236852b61309b1a06444de1881cda8b6203b02dfe1746f
|
|
| MD5 |
0b38552bcfec8be09a428c2db1e5d5df
|
|
| BLAKE2b-256 |
f0632eb7b8970469a9cf7126cfa2c8530b51318fa366600702d09dafaab010ef
|
File details
Details for the file nano_template-0.1.0-cp39-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: nano_template-0.1.0-cp39-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 33.3 kB
- Tags: CPython 3.9+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8479288564045cd30127272e0424268ea8a5d07c0087ceb6b135424343741575
|
|
| MD5 |
1567f5aa1091ebad52be423c33e9fb93
|
|
| BLAKE2b-256 |
e2c0b9638c65487055422301e52101b5d832afa255bc6055668181afa93fcda2
|
File details
Details for the file nano_template-0.1.0-cp39-abi3-macosx_10_9_x86_64.whl.
File metadata
- Download URL: nano_template-0.1.0-cp39-abi3-macosx_10_9_x86_64.whl
- Upload date:
- Size: 33.1 kB
- Tags: CPython 3.9+, macOS 10.9+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
30b784a6981943e8e6577da426472fb0f0c23d3c386dab693cccd85e3f8f3e1d
|
|
| MD5 |
08885578daf949131b63241f1989f623
|
|
| BLAKE2b-256 |
8f09ba4c1ce558d5bc14380acaa86d041b31d1bf160aee5e1fc57866ed90a9ea
|