engine

package
v0.60.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 12, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package engine is the Liquid dialect filex's editable templates are written in: the mail and public-page templates an administrator can change (internal/templates). It is the ONE definition of that dialect - which tags and filters exist, how output is escaped, where `include` reads from - and it is compiled twice: into the server, which renders the templates filex ships, and into the WebAssembly guest (internal/templates/sandbox/guest), which renders a template somebody edited. A template therefore means the same thing wherever it runs.

⚠⚠ Nothing here may import server packages. The guest is built for GOOS=wasip1 from this package and the Liquid library alone; whatever the filters need from the server (a sentence of the catalogue, a size in the reader's language) they ask through Host, which the server answers in-process and the guest answers through a host import.

The rules, each with the measurement that made it (docs/TEMPLATES.md, "Security"):

  • Output is HTML-escaped (Mode HTML): `{{ x }}` cannot write markup, whatever x holds. osteele/liquid's own `safe` filter would lift that, so `safe` is redefined to do nothing; the only values written as they are come from filex itself (MarkSafe) or from a filter of this package that escaped them first (escape, newline_to_br, link_to, t_html).
  • `escape` and `escape_once` answer escaped text that is not escaped a second time, `capture` keeps what it captured as the HTML it already is, and `newline_to_br` escapes the text before it adds the <br>: without these three, measured, the library's own versions printed "&amp;lt;" where the reader should have seen "<".
  • `include` and `render` read only the shared pieces handed to New (Options.Partials). The library's default store reads files from the process's working directory - `{% include 'go.mod' %}` printed go.mod.
  • `cycle` is not part of the dialect: its renderer shares an error variable between renders (osteele/liquid #150, a data race).

What this package does NOT do is bound the work a template can make: Liquid has loops and string building, and the library has no budget (`{% for i in (1..1000000000) %}{% endfor %}` runs to the end, a string doubled thirty times is ten gigabytes). A template only filex wrote is rendered here directly; every edited one runs inside the sandbox, whose time, memory and output ceilings are hard.

Index

Constants

This section is empty.

Variables

View Source
var ErrNoHost = errors.New("this template filter needs the server")

ErrNoHost is what a filter that needs the server answers without one.

Functions

func Check

func Check(o Options, name, src string) error

Check parses src and reports its first syntax error, without rendering.

func MarkSafe

func MarkSafe(data map[string]any, paths []string)

MarkSafe wraps the values at the given dotted paths as HTML that is written as it is - markup filex itself produced (the content a layout frames, the page's theme stylesheet). A path that does not exist, or does not end at a string, is left alone.

func New

func New(o Options) *liquid.Engine

New is a Liquid engine speaking filex's dialect.

func Render

func Render(o Options, name, src string, data map[string]any) (string, error)

Render parses and renders src. name is the template's name in error messages ("mail.share"); every error carries the line it happened on.

func RenderTo

func RenderTo(w io.Writer, o Options, name, src string, data map[string]any) error

RenderTo is Render writing to w.

func Safe

func Safe(html string) any

Safe is a value written as it is: markup filex produced. Callers that render in-process use it in their data instead of MarkSafe.

func SafeURL

func SafeURL(u string) string

SafeURL is u when it is an address a link may carry - http(s), mailto:, tel:, or relative (a path, a query, a fragment) - and "#" otherwise.

Types

type Host

type Host interface {
	Call(fn string, args []any) (string, error)
}

Host answers what a filter needs from the server. fn is one of:

"t"     args [key, vars]        → the sentence, placeholders filled
"tpl"   args [key, vars]        → the sentence with its placeholders as written
"bytes" args [n]                → a size in the reader's language ("1.2 MB")

key is a catalogue key without the `server.` prefix ("mail.greeting"); vars is a map[string]string, and its "count" entry picks the plural form.

type Mode

type Mode int

Mode is how a template's output is written.

const (
	// HTML escapes every `{{ }}` output: an HTML mail body, a page.
	HTML Mode = iota
	// Text writes outputs as they are: a mail's subject line and its
	// plain-text body, which no browser parses.
	Text
)

type Options

type Options struct {
	Mode Mode
	Host Host
	// Partials are the shared pieces `{% include 'name' %}` may read, by name.
	// Nothing else is readable: there is no file system behind include.
	Partials map[string]string
	// Strict makes a variable the data does not have an error rather than an
	// empty string - how a template is checked before it is saved, against
	// sample data that has every variable. Real renders are lax: an optional
	// value that is missing must never cost somebody their mail.
	Strict bool
}

Options configures one render.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL