wire.loader
import wire.loader
wiredoes 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
| Field | Type | Description |
|---|---|---|
root | The directory every path resolves inside. | |
extension | The 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