diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-19 08:17:30 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-19 08:17:30 +0200 |
| commit | da9cf402ceed8102aec1a9d008f8e918a23d39f3 (patch) | |
| tree | 3c9a7bd748f886633117cce7059ba304c23541cb /lib/render/template.mli | |
| parent | a526d934cea17ff1b76ddad5c5f2934fb85c11cb (diff) | |
| download | colitur-da9cf402ceed8102aec1a9d008f8e918a23d39f3.tar.gz colitur-da9cf402ceed8102aec1a9d008f8e918a23d39f3.zip | |
feat(render): template renderer with mandatory escaping
Every interpolated value is escaped for the template's flavour; the
template's own literal text never is, because that is the author's
markup. There is no raw form, so a template cannot opt out.
Scope is a stack with outward fallback, so a grid template can reach the
year number from inside a week without the view duplicating it into
every cell.
A missing key renders empty -- the one deliberate silence, so a template
survives a rite that does not set every optional field.
Mutation-tested: dropping the Escape.apply call reddens the
data-cannot-escape-flavour case.
Diffstat (limited to 'lib/render/template.mli')
| -rw-r--r-- | lib/render/template.mli | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/lib/render/template.mli b/lib/render/template.mli index 3f9ef97..4118496 100644 --- a/lib/render/template.mli +++ b/lib/render/template.mli @@ -26,3 +26,12 @@ type node = (** Never raises; a malformed template is an [Error] with a human-readable reason, because the template is user input. *) val parse : string -> (node list, string) result + +(** Render against a value. Escaping is applied to every interpolated value and + NEVER to the template's own literal text, which is the author's markup. + A missing key renders as the empty string -- the one deliberate silence, so + that a template survives a rite that does not set every optional field. *) +val render : flavour:Escape.flavour -> node list -> value -> string + +(** [parse] then [render]. *) +val render_string : flavour:Escape.flavour -> string -> value -> (string, string) result |
