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.loader

import wire.loader

wire does not re-export this module, so it is reached only by importing it directly.

Turning the path written in an x-include into a file on disk, and refusing to when it points somewhere it should not.

The root is a boundary, not a starting point

Every template path resolves inside the root directory and nowhere else. A path that climbs out of it with .., and an absolute path that names somewhere else entirely, are both refused rather than followed.

That matters because template paths are not always written by the person who wrote the template. The moment a path is built out of anything a request supplied, as x-include="themes/{{ theme }}/head" does, an unbounded loader turns an include into a way to read any file the process can reach. Wire treats the root as a boundary so that the worst a hostile value can do is fail to find a template.

Symbolic links are followed and then checked, so a link inside the root pointing outside it is refused too.

Classes

Loader

class wire.loader.Loader

Finds template files under one root directory.

Fields

FieldTypeDescription
rootThe directory every path resolves inside.
extensionThe extension tried when the path as written names no file.

Constructor

wire.loader.Loader(root: string, extension: ?string)

Parameters

  • root (string)
  • extension (?string)

Loader.resolve()

wire.loader.Loader.resolve(path: string, from: ?string, line: ?number, column: ?number) -> string

The file path names, as an absolute path.

The path is tried as written first and then with the configured extension appended, so render('home') finds home.html while render('home.txt') finds exactly that.

from and line and column describe where the include was written and are only used to place the error.

Parameters

  • path (string)
  • from (?string)
  • line (?number)
  • column (?number)

Returns string

Raises TemplateNotFoundError when there is no such file, or when the path resolves outside the root.

Loader.read()

wire.loader.Loader.read(full: string) -> string

The contents of the file at full.

Parameters

  • full (string)

Returns string

Raises TemplateNotFoundError when the file cannot be read.

Loader.fingerprint()

wire.loader.Loader.fingerprint(full: string) -> ?string

What the file at full looks like now, for telling a cached template apart from a changed one.

Both the modification time and the size are used, because a file rewritten within the same second still almost always changes length. A file that cannot be stated fingerprints as nil, which makes the cache treat it as changed and read it again.

Parameters

  • full (string)

Returns ?string


2026, Richard Ore and The Zuri Contributors