Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

wire.compile

import wire.compile

wire does 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

FieldTypeDescription
textThe literal characters, or nil when this is an expression.
valueThe 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

FieldTypeDescription
kindWhat kind of instruction this is.
lineThe line of the tag it came from, or 0.
columnThe 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

FieldTypeDescription
segmentsThe literal and interpolated pieces, in order.
contextThe escaping context every interpolation in this run needs.
raw_literalTrue 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

FieldTypeDescription
textThe 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

FieldTypeDescription
dataThe text between the delimiters.

Constructor

wire.compile.Comment(data: string)

Parameters

  • data (string)

Attribute

class wire.compile.Attribute

One attribute of an element.

Fields

FieldTypeDescription
nameThe attribute’s name.
segmentsThe literal and interpolated pieces of its value.
contextThe escaping context its interpolations need, decided by the attribute’s name.
url_listTrue when the attribute holds several URLs rather than one, so each has to be checked on its own.
url_descriptorsTrue 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

FieldTypeDescription
tagThe tag name, as it will be written.
attributesThe attributes written literally on the element.
spreadsExpressions giving further attributes, from x-attr, applied after the literal ones so a computed value wins.
childrenThe instructions for the element’s children.
voidTrue for an element written without a closing tag.
contentAn expression replacing the element’s children, from x-text or x-html, or nil.
content_rawTrue 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

FieldTypeDescription
childrenThe instructions.

Constructor

wire.compile.Group(children: list)

Parameters

  • children (list)

Branch

class wire.compile.Branch

One arm of a conditional chain.

Fields

FieldTypeDescription
testThe expression being tested, or nil for the final x-else.
negateTrue when the arm renders on a falsy test, which is what x-not means.
bodyThe 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

FieldTypeDescription
branchesThe 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

FieldTypeDescription
sequenceThe expression giving the thing to iterate.
value_nameThe name each value is bound to, or nil.
key_nameThe name each key or index is bound to, or nil.
loop_nameThe name the loop’s own metadata is published under.
bodyThe 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

FieldTypeDescription
pathThe literal and interpolated pieces of the path.
contextThe element the include sits inside, so a partial holding table rows is parsed knowing that, or nil for a…
variablesAn expression giving further variables for the included template, from x-with, or nil.
onlyTrue when the included template sees only what x-with gave it.
bodyThe 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

FieldTypeDescription
nameThe region’s name.
bodyThe 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

FieldTypeDescription
pathThe file it was compiled from, or the source name given for a template compiled from a string.
bodyThe instructions making up the template’s own output.
blocksThe regions this template defines, keyed by name, from x-define.
extendsThe literal and interpolated pieces of the base template’s path, or nil when this template extends nothing.
contextThe element this template was compiled to sit inside, or nil when it was compiled on its own.
fingerprintWhat the file looked like when it was read, so a cached template can tell whether the file has changed…
errorsThe 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

FieldTypeDescription
pathThe template being compiled, for error messages.
compactWhether whitespace-only text is dropped.
commentsWhether 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