Last updated:
0 purchases
artlesstemplate 0.4.1
artless-template
Artless and small template library for server-side rendering.
Artless-template allows to generate HTML, using template files or/and natively Python objects. The library encourages approaches like HTMX and No-JS.
Features:
Small and simple code base (less than 200 LOC).
No third party dependencies (standart library only).
Table of Contents:
Install
Usage
Template and tags usage
Template and components usage
Asynchronous functions
Performance
Rodmap
Install
$ pip install artless-template
Usage
Basically, you can create any tag with any name, attributes, text and child tags:
from artless_template import Tag as t
div = t("div")
print(div)
<div></div>
div = t("div", attrs={"class": "some-class"}, text="Some text")
print(div)
<div class="some-class">Some text</div>
div = t(
"div",
attrs={"class": "some-class"},
text="Div text",
children=[t(span, text="Span 1 text"), t(span, text="Span 2 text")]
)
print(div)
<div class="some-class"><span>Span 1 text</span><span>Span 2 text</span>Div text</div>
button = t("button", attrs={"onclick": "function() {alert('hello');}"}, text="Say Hello")
print(button)
<button onclick="function() {alert('hello');}">Say Hello</button>
Template and tags usage
Create templates/index.html with contents:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>@title</title>
</head>
<body>
<main>
<section>
<h1>@header</h1>
<table>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Admin</th>
</tr>
</thead>
@users
</table>
</section>
</main>
</body>
</html>
from typing import final
from pathlib import Path
from random import randint
from dataclasses import dataclass
from artless_template import read_template, Tag as t
TEMPLATES_DIR: Path = Path(__file__).resolve().parent / "templates"
@final
@dataclass(frozen=True, slots=True, kw_only=True)
class UserModel:
name: str
email: str
is_admin: bool
users = [
UserModel(
name=f"User_{_}", email=f"user_{_}@gmail.com", is_admin=bool(randint(0, 1))
)
for _ in range(10_000)
]
users_markup = t(
"tbody",
children=[
t(
"tr",
children=[
t("td", text=user.name),
t("td", text=user.email),
t("td", text="+" if user.is_admin else "-"),
],
)
for user in users
],
)
context = {
"title": "Artless-template example",
"header": "Users list",
"users": users_markup,
}
template = read_template(TEMPLATES_DIR / "index.html").render(**context)
Template and components usage
<!DOCTYPE html>
<html lang="en">
...
<body>
<main>
@main
</main>
</body>
</html>
from artless_template import read_template, Component, Tag as t
...
class UsersTableComponent:
def __init__(self, count: int):
self.users = [
UserModel(
name=f"User_{_}", email=f"user_{_}@gmail.com", is_admin=bool(randint(0, 1))
)
for _ in range(count)
]
def view(self):
return t(
"table",
children=[
t(
"thead",
children=[
t(
"tr",
children=[
t("th", text="Name"),
t("th", text="Email"),
t("th", text="Admin"),
]
)
]
),
t(
"tbody",
children=[
t(
"tr",
children=[
t("td", text=user.name),
t("td", text=user.email),
t("td", text="+" if user.is_admin else "-"),
],
)
for user in self.users
]
)
]
)
template = read_template(TEMPLATES_DIR / "index.html").render(main=UsersTableComponent(100500))
Asynchronous functions
The library provides async version of io-bound function - read_template. An asynchronous function has a prefix and called aread_template.
from artless_template import aread_template
template = await aread_template("some_template.html")
...
Performance
Performance comparison of the most popular template engines and artless-template library.
The benchmark render a HTML document with table of 10 thousand user models.
Run benchmark:
$ python -m bemchmarks
Sorted results on i5 laptop (smaller is better):
{'mako': 0.05390851100673899, 'jinja': 0.25190652400488034, 'artless': 0.4437121729715727, 'dtl': 1.03557736199582}
Mako (0.05390 sec.)
Jinja2 (0.25190 sec.)
Artless-template (0.44371 sec.)
Django templates (1.03557 sec.)
The performance of artless-template is better than the Django template engine, but worse than Jinja2 and Mako.
Roadmap
Simplify the Tag constructor.
Create async version of read_template() - aread_template().
Cythonize CPU/RAM-bound of code.
Write detailed documentation with Sphinx.
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.