artless-template 0.4.1

Creator: bradpython12

Last updated:

Add to Cart

Description:

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.

License

For personal and professional use. You cannot resell or redistribute these repositories in their original state.

Customer Reviews

There are no reviews.