Skip to content

Templating redux#13

Draft
Tronic wants to merge 2 commits into
mainfrom
templating-redux
Draft

Templating redux#13
Tronic wants to merge 2 commits into
mainfrom
templating-redux

Conversation

@Tronic

@Tronic Tronic commented Jul 5, 2026

Copy link
Copy Markdown
Member

A new templating implementation replacing the old one introduced in version 1.3. The templates are immutable objects instantiated at render time with dynamic content but not internally preserving such content anymore. We are running far faster than the old template system, and can now properly support for loops for nested items (sub templates) which the old one did not.

The templating is for the highest possible performance and also to ease the construction of complex documents.

This is intended for 2.0 release, as it breaks compatibility with 1.3 templates.

New Syntax

from html5tagger import Document, E, Template

# Define the reusable templates once
Page = Document(E.Title).h1.Title.ul.Items @ Template
Item = Template(E.li.span(class_="name").Name._(": ").span(class_="price").Price("N/A"))

# Super fast rendering just fills in the dynamic data
def render(products: list) -> str:
    return Page(
        Title="Product List",
        Items=[Item(**product) for product in products],
    )

html = render([
    {"Name": "Apple", "Price": "$1.20"},
    {"Name": "Banana"},
])
<!DOCTYPE html>
<meta charset="utf-8">
<title>Product List</title>
<h1>Product List</h1>
<ul>
  <li><span class=name>Apple</span>: <span class=price>$1.20</span>
  <li><span class=name>Banana</span>: <span class=price>N/A</span>
</ul>

Performance

Generated HTML length: 20573 bytes
Number of products:    100

Single page render time (averaged over 1000 renders):
  Template callable:     0.189 ms  (1.89 µs/item)
  Build from scratch:    0.812 ms  (8.12 µs/item)

Template is 4.3x faster

The benchmark script shows difference between no templating (built from scratch) and the new system. The old system was slower than building from scratch and not really comparable here. Python web frameworks take some 0.5ms to even Hello World. The build from scratch for a large document can reduce the maximal req/s, while if templated it hardly affects performance.

Tronic and others added 2 commits July 5, 2026 04:50
- Remove mutable template-tag leftovers:
  - Builder.render(), _render_piece(), _render_value()
  - Builder.__setattr__() slot setter
  - trailing-underscore handling for placeholders
  - debug _optimize() method
- Update tests to use immutable Template objects only
- Update README and Template docstrings for new API
- Fix benchmark unused imports and formatting
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant