wire.compile
import wire.compile
wiredoes not re-export this module, so it is reached only by importing it directly.
Turning a parsed template into the instruction tree the renderer walks.
Wire compiles rather than substitutes. A template is parsed once, every expression in it is parsed once, every directive is resolved once, and what comes out is a tree of plain instructions that holds no reference back to the document it came from. Rendering that tree is then a walk with no parsing in it at all, which is what lets the same page be rendered thousands of times from one compile, and what lets the renderer know the exact escaping context of every interpolation instead of guessing at it.
Compiling is also where a template’s mistakes are found. An unknown
directive, an expression that does not parse, an x-else with no x-if
in front of it, the same region defined twice: all of them are reported
here, once, rather than on the request that happens to reach them.
Functions
compile()
wire.compile.compile(source: string, path: string, context, options: ?dict) -> Template
Compiles source into a Template.
context names the element the result will sit inside, and should be
nil for a template rendered on its own. options takes compact
(drop whitespace-only text, default false) and comments (keep HTML
comments, default false).
import wire
var template = wire.compile.compile(
'<p x-if="user">Hello {{ user.name }}</p>', 'greeting.html', nil, nil
)
Parameters
source(string)path(string)context(?string)options(?dict)
Returns Template
Raises TemplateSyntaxError
Classes
Segment
class wire.compile.Segment
One piece of a run of text or of an attribute value: either literal characters or an expression to evaluate.
Fields
| Field | Type | Description |
|---|---|---|
text | The literal characters, or nil when this is an expression. | |
value | The expression, or nil when this is literal text. |
Constructor
wire.compile.Segment(text, value)
Parameters
text(?string)value(?Expression)
Instruction
class wire.compile.Instruction
The base of every instruction, carrying the kind the renderer switches on and the place in the source it came from.
Fields
| Field | Type | Description |
|---|---|---|
kind | What kind of instruction this is. | |
line | The line of the tag it came from, or 0. | |
column | The column of that tag, or 0. |
Constructor
wire.compile.Instruction(kind: string, line: number, column: number)
Parameters
kind(string)line(number)column(number)
Text
class wire.compile.Text < Instruction
A run of text, possibly with interpolations in it.
Fields
| Field | Type | Description |
|---|---|---|
segments | The literal and interpolated pieces, in order. | |
context | The escaping context every interpolation in this run needs. | |
raw_literal | True when the literal pieces are written out unchanged, which is the case inside a <script> or a <style>… |
Constructor
wire.compile.Text(segments: list, context: string, raw_literal: bool)
Parameters
segments(list)context(string)raw_literal(bool)
Raw
class wire.compile.Raw < Instruction
Characters written out exactly as they are, used for the doctype.
Fields
| Field | Type | Description |
|---|---|---|
text | The characters. |
Constructor
wire.compile.Raw(text: string)
Parameters
text(string)
Comment
class wire.compile.Comment < Instruction
An HTML comment that survived into the output.
Fields
| Field | Type | Description |
|---|---|---|
data | The text between the delimiters. |
Constructor
wire.compile.Comment(data: string)
Parameters
data(string)
Attribute
class wire.compile.Attribute
One attribute of an element.
Fields
| Field | Type | Description |
|---|---|---|
name | The attribute’s name. | |
segments | The literal and interpolated pieces of its value. | |
context | The escaping context its interpolations need, decided by the attribute’s name. | |
url_list | True when the attribute holds several URLs rather than one, so each has to be checked on its own. | |
url_descriptors | True when each URL in the list may be followed by a descriptor, as srcset allows and ping does not. |
Constructor
wire.compile.Attribute(name: string, segments: list)
Parameters
name(string)segments(list)
Element
class wire.compile.Element < Instruction
An element, with everything about it already worked out.
Fields
| Field | Type | Description |
|---|---|---|
tag | The tag name, as it will be written. | |
attributes | The attributes written literally on the element. | |
spreads | Expressions giving further attributes, from x-attr, applied after the literal ones so a computed value wins. | |
children | The instructions for the element’s children. | |
void | True for an element written without a closing tag. | |
content | An expression replacing the element’s children, from x-text or x-html, or nil. | |
content_raw | True when content came from x-html and must not be escaped. |
Constructor
wire.compile.Element(tag: string, line: number, column: number)
Parameters
tag(string)line(number)column(number)
Group
class wire.compile.Group < Instruction
A run of instructions with nothing of its own, which is what a
<template> carrying a directive leaves behind.
Fields
| Field | Type | Description |
|---|---|---|
children | The instructions. |
Constructor
wire.compile.Group(children: list)
Parameters
children(list)
Branch
class wire.compile.Branch
One arm of a conditional chain.
Fields
| Field | Type | Description |
|---|---|---|
test | The expression being tested, or nil for the final x-else. | |
negate | True when the arm renders on a falsy test, which is what x-not means. | |
body | The instruction to render when the arm is taken. |
Constructor
wire.compile.Branch(test, negate: bool, body)
Parameters
test(?Expression)negate(bool)body(Instruction)
Conditional
class wire.compile.Conditional < Instruction
A chain of x-if, x-elif and x-else, or a lone x-if.
Fields
| Field | Type | Description |
|---|---|---|
branches | The arms, in the order they were written. |
Constructor
wire.compile.Conditional(branches: list, line: number, column: number)
Parameters
branches(list)line(number)column(number)
Loop
class wire.compile.Loop < Instruction
A repetition, from x-for.
Fields
| Field | Type | Description |
|---|---|---|
sequence | The expression giving the thing to iterate. | |
value_name | The name each value is bound to, or nil. | |
key_name | The name each key or index is bound to, or nil. | |
loop_name | The name the loop’s own metadata is published under. | |
body | The instruction rendered once per entry. |
Constructor
wire.compile.Loop(sequence, line: number, column: number)
Parameters
sequence(Expression)line(number)column(number)
Include
class wire.compile.Include < Instruction
Another template rendered in this instruction’s place.
Fields
| Field | Type | Description |
|---|---|---|
path | The literal and interpolated pieces of the path. | |
context | The element the include sits inside, so a partial holding table rows is parsed knowing that, or nil for a… | |
variables | An expression giving further variables for the included template, from x-with, or nil. | |
only | True when the included template sees only what x-with gave it. | |
body | The instructions for the include’s own children, which the included template can place with… |
Constructor
wire.compile.Include(path: list, context, line: number, column: number)
Parameters
path(list)context(?string)line(number)column(number)
Slot
class wire.compile.Slot < Instruction
A region an extending template may replace, from x-slot.
Fields
| Field | Type | Description |
|---|---|---|
name | The region’s name. | |
body | The instructions rendered when nothing has replaced it. |
Constructor
wire.compile.Slot(name: string, body: list, line: number, column: number)
Parameters
name(string)body(list)line(number)column(number)
Super
class wire.compile.Super < Instruction
The definition this one replaces, from x-super.
Constructor
wire.compile.Super(line: number, column: number)
Parameters
line(number)column(number)
Template
class wire.compile.Template
A compiled template, ready to render as many times as you like.
Nothing here changes while a render is running, so one of these can be shared.
Fields
| Field | Type | Description |
|---|---|---|
path | The file it was compiled from, or the source name given for a template compiled from a string. | |
body | The instructions making up the template’s own output. | |
blocks | The regions this template defines, keyed by name, from x-define. | |
extends | The literal and interpolated pieces of the base template’s path, or nil when this template extends nothing. | |
context | The element this template was compiled to sit inside, or nil when it was compiled on its own. | |
fingerprint | What the file looked like when it was read, so a cached template can tell whether the file has changed… | |
errors | The parse errors the HTML parser found in the source. |
Constructor
wire.compile.Template(path: string, context)
Parameters
path(string)context(?string)
Compiler
class wire.compile.Compiler
Compiles one template’s source.
There is one of these per compile and it is thrown away afterwards; the
Template it produces holds nothing that points back at it.
Fields
| Field | Type | Description |
|---|---|---|
path | The template being compiled, for error messages. | |
compact | Whether whitespace-only text is dropped. | |
comments | Whether comments survive into the output. |
Constructor
wire.compile.Compiler(path: string, options: ?dict)
Parameters
path(string)options(?dict)
Compiler.compile()
wire.compile.Compiler.compile(source: string, context) -> Template
Compiles source as a template that will sit inside context, or on
its own when context is nil.
Parameters
source(string)context(?string)
Returns Template
Raises TemplateSyntaxError
Compiler.children()
wire.compile.Compiler.children(nodes: list) -> list
Compiles a list of sibling nodes, tying conditional chains together as it goes.
Parameters
nodes(list)
Returns list
Raises TemplateSyntaxError
Compiler.other()
wire.compile.Compiler.other(node) -> ?Instruction
Compiles a node that is not an element, or returns nil when it
contributes nothing.
Parameters
node(Node)
Returns ?Instruction
Compiler.text()
wire.compile.Compiler.text(node) -> Text
Compiles a text node, working out its escaping context from the element it sits in.
Parameters
node(Text)
Returns Text
Compiler.element()
wire.compile.Compiler.element(node) -> Instruction
Compiles an element, wrapping it in whatever its directives ask for.
The wrapping runs outside in: a repetition holds a condition, a
condition holds an include, and the element itself is innermost. That
order is what lets an x-if on a repeated element see the loop’s own
variables.
Parameters
node(Element)
Returns Instruction
Raises TemplateSyntaxError
Compiler.expression_of()
wire.compile.Compiler.expression_of(node, directive: string) -> Expression
Parses the expression a directive carries.
Parameters
node(Element)directive(string)
Returns Expression
Raises TemplateSyntaxError
Compiler.name_of()
wire.compile.Compiler.name_of(node, directive: string) -> string
Reads the bare identifier a naming directive carries.
Parameters
node(Element)directive(string)
Returns string
Raises TemplateSyntaxError when it is not a plain name.
Compiler.path_segments()
wire.compile.Compiler.path_segments(value: string, node) -> list
Splits a template path into its literal and interpolated pieces.
A path is read as text rather than as an expression, so
x-include="header.html" names a file instead of reading a html key
off a header variable. Use {{ }} where part of it is computed.
Parameters
value(string)node(Element)
Returns list
Raises TemplateSyntaxError
Compiler.segments()
wire.compile.Compiler.segments(value: string, context: string, host) -> list
Splits text into its literal and interpolated pieces.
Parameters
value(string)context(string)host(?Node) — The node the text belongs to, for error positions.
Returns list
Raises TemplateSyntaxError
2026, Richard Ore and The Zuri Contributors