Skip to main content

Artless and small template library for server-side rendering.

Project description

artless-template

Build Status PyPI - Python Version PyPI Version Code Coverage Maintainability

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

$ 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", {"class": "some-class"}, "Some text")
print(div)
<div class="some-class">Some text</div>

div = t("div", {"class": "some-class"}, "Div text", [t(span, None, "Span 1 text"), t(span, None, "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", {"onclick": "function() {alert('hello');}"}, "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",
    None,
    None,
    [
        t(
            "tr",
            None,
            None,
            [
                t("td", None, user.name),
                t("td", None, user.email),
                t("td", None, "+" 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",
            None,
            None,
            [
                t(
                    "thead",
                    None,
                    None,
                    [
                        t(
                            "tr",
                            None,
                            None,
                            [
                                t("th", None, "Name"),
                                t("th", None, "Email"),
                                t("th", None, "Admin"),
                            ]
                        )
                    ]
                ),
                t(
                    "tbody",
                    None,
                    None,
                    [
                        t(
                            "tr",
                            None,
                            None,
                            [
                                t("td", None, user.name),
                                t("td", None, user.email),
                                t("td", None, "+" if user.is_admin else "-"),
                            ],
                        )
                        for user in self.users
                    ]
                )
            ]
        )

template = read_template(TEMPLATES_DIR / "index.html").render(main=UsersTableComponent(100500))

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.009, 'jinja': 0.029, 'artless': 0.048, 'dtl': 0.157}
  1. Mako (0.009 sec.)
  2. Jinja2 (0.029 sec.)
  3. Artless-template (0.048 sec.)
  4. Django templates (0.157 sec.)

The performance of artless-template is better than the Django template engine, but worse than Jinja2 and Mako.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

artless_template-0.2.0.tar.gz (7.9 kB view details)

Uploaded Source

Built Distribution

artless_template-0.2.0-py3-none-any.whl (6.4 kB view details)

Uploaded Python 3

File details

Details for the file artless_template-0.2.0.tar.gz.

File metadata

  • Download URL: artless_template-0.2.0.tar.gz
  • Upload date:
  • Size: 7.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.0.0 CPython/3.12.3

File hashes

Hashes for artless_template-0.2.0.tar.gz
Algorithm Hash digest
SHA256 7d710f57c37c2c5849f9df92e5e661c17fac80b9cebd297f264310be7a11576f
MD5 eeadb4022cd2ca08e7ff994575355030
BLAKE2b-256 c92f3246ea2575f8b4d20220c5801f898e34c029a57aec9d6801661527019695

See more details on using hashes here.

Provenance

File details

Details for the file artless_template-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for artless_template-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 93788d9d0be1fc5008e34482c0c423df9d321c744f342c03117e911894ccde6d
MD5 d5832b98597d2dc9e65369747867c1d2
BLAKE2b-256 3d3e47014acb135990610c3038fd08e83ec8bd7229b388a7f0354f8a2ac00838

See more details on using hashes here.

Provenance

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page