Templates#

Templates use {{name}} placeholders (escaped when the engine runs with escape=True) and {{{name}}} raw placeholders (never escaped). These are the parser and binder the engine uses; a Template keeps the compiled form.

extract(template: str) → list[Chunk][source]#

Split a template into static text and {{slot}} / {{{raw}}} chunks.

Whitespace around a slot name is ignored ({{ title }} is title).

Parameters:

template – The template source.

Returns:

list[Chunk] – The chunks in order.

Raises:

AnzaError – TEMPLATE for an unclosed {{ or {{{, or an empty placeholder.

Example

>>> from anza import extract
>>> extract("<p>{{ name }} {{{html}}}</p>")
[Chunk(kind='static', value='<p>'), Chunk(kind='slot', value='name'),
 Chunk(kind='static', value=' '), Chunk(kind='raw', value='html'),
 Chunk(kind='static', value='</p>')]
>>> extract("<p>{{name</p>")
Traceback (most recent call last):
    ...
anza.errors.AnzaError: [Anza:TEMPLATE] Unclosed slot placeholder '{{' in template
string(chunks: list[Chunk], params: Any = None, escape: bool = False) → str[source]#

Bind params into parsed chunks.

Values become text as the contract specifies: strings as is, True / False as true / false, integers in decimal, integral floats without .0, dicts, lists and tuples as compact JSON, and a missing key or None as nothing. Objects are read through their public, non-callable attributes only: {{__class__}} or a method name renders empty.

This compiles the chunks on every call; keep a Template to bind the same template repeatedly.

Parameters:
  • chunks – The output of extract().

  • params – A dict, (key, value) pairs, or any object.

  • escape – HTML-escape {{slot}} values; {{{raw}}} values never are.

Returns:

str – The rendered text.

Example

>>> from anza import extract, string
>>> chunks = extract("<b>{{name}}</b> {{{note}}} {{n}} {{tags}}")
>>> string(chunks, {"name": "<i>", "note": "<em>ok</em>", "n": 2.0, "tags": ["a"]})
'<b><i></b> <em>ok</em> 2 ["a"]'
>>> string(chunks, {"name": "<i>", "note": "<em>ok</em>"}, escape=True)
'<b>&lt;i&gt;</b> <em>ok</em>  '

Warning

Without escape=True values are inserted without HTML escaping.

escape_html(text: str) → str[source]#

HTML-escape text for element content or a quoted attribute value.

& < > " ' become &amp; &lt; &gt; &quot; &#39;, byte for byte like the Rust and TypeScript engines (html.escape writes &#x27; instead).

Parameters:

text – The text to escape.

Returns:

str – The escaped text.

Example

>>> from anza import escape_html
>>> escape_html('''<a href="x">Tom & Jerry's</a>''')
'&lt;a href=&quot;x&quot;&gt;Tom &amp; Jerry&#39;s&lt;/a&gt;'
class Chunk(kind: Literal['static', 'slot', 'raw'], value: str)[source]#

One piece of a parsed template.

static text, a slot ({{name}}, escaped when the engine runs with escape=True) or a raw slot ({{{name}}}, never escaped).

Example

>>> from anza import Chunk
>>> Chunk(kind="slot", value="title")
Chunk(kind='slot', value='title')
kind: Literal['static', 'slot', 'raw']#

"static", "slot" or "raw".

value: str#

The static text, or the slot name (whitespace stripped).