Standard library · The web
web/tmpl
Imported as import "web/tmpl" as tmpl, its names are then tmpl.…. Every signature below is the one the checker infers.
The runtime half of the template engine: what a generated template calls.
A template is not read at run time. tools/tmplgen.rill turns it into Rill — one function per template, static text as string literals and everything else as the code it stands for — and the Rill compiler compiles that. So a render is a run of appends to a builder with nothing to parse, nothing to look up by name, and no branch that asks what kind of tag this was.
What is left for run time is here: how a value becomes text, and how text becomes safe to put in a page.
b = strbuf() greet(b, "Ada & co") # the generated function println(strbuf_str(b))
render is a trait, so <%= x %> costs what the type of x costs and no more: an Int goes into the builder as digits with no escaping and no string in between, a Str is escaped, and a type of your own is whatever its impl Render says. The choice is made when the program is compiled, not when the page is rendered.
Traits
trait Render(a)
The value a render answers with means nothing and every caller drops it. A Rill for is worth zero, and these end in one.
render(StrBuf, a) -> Int
trait Raw(a)
What <%! x %> writes: the text as it stands, for a value that is already markup. Nothing checks that claim, which is why it has a mark of its own.
raw(StrBuf, a) -> Int
Implementations
impl Render(Str)impl Render(Int)impl Render(Float)impl Render(Bool)impl Raw(Str)
Functions
fn esc_into(b: StrBuf, s: Str) -> Int
The five bytes that can change what a page means: &, <, >, " and '. Almost no string holds one, so the string is looked over first and copied whole when it does not — one length and one copy, which is what a static piece of the template costs too. Only a string that does hold one is walked a byte at a time, and even then nothing is allocated: a byte goes into the builder as a byte.
b = strbuf() tmpl.esc_into(b, "Ada & co") strbuf_str(b) # => Ada & co
fn esc(s: Str) -> Str
The same as a string, for a caller that wants one rather than a builder.
tmpl.esc("<a href=\"x\">") # => <a href="x"> tmpl.esc("plain") # => plain