The Frontmatter
Every template begins with a --- frontmatter header declaring its inputs. The
whole block is consumed (nothing leaks into the output); the body then uses bare
${ name } references — no inline types.
---params { service: iri endpoint: iri optional classes: iri[] min 1 tags: string[] optional max 5 people: { id: iri, name: string optional }[] min 1 limit: int}---- Sections are brace-delimited.
params { … }is mandatory;example … { … }blocks are optional (see Example blocks).paramsandexampleare keywords only here, so any parameter name is allowed. - Types:
iri,pname,string,int,decimal,double,bool,date,dateTime,time,literal(<dt>),term,raw. - Modifiers (in order):
<type> ['[]'] ['optional'] ['min' N] ['max' N].[]marks an array;min/maxbound its length;optionalmarks that a value may be omitted. rawinserts verbatim with no escaping — the single auditable unsafe hatch, visible in the header.
The engine validates the whole context against the header up front (missing
required, unknown key, wrong type, out-of-range cardinality). Typing is strict:
"10" is not an int, a list is not a scalar.
Values
Section titled “Values”${ name } / ${ p.id } reference declared params or loop variables. The same
reference serializes differently by construct: standalone → per its declared
type; inside $"…" → string-escaped; inside $<…> → percent-encoded.
Keywords and type names are case-insensitive; variable names, IRIs, and string content are case-sensitive.
Comments
Section titled “Comments”---params { service: iri # the endpoint this query federates to people: { id: iri # stable identifier name: string }[] # one row per person}# everything below is preview-onlyexample demo { service: <http://dbpedia.org/sparql> people: [ { id: <http://ex.org/1>, name: "Ada" }, # the first row { id: <http://ex.org/2>, name: "Grace" } ]}---# runs to the end of the line. Put one wherever an item may start — at any
nesting depth — or trail an item on the same line: between sections, between
declarations or bindings, between the fields of a record type, and between the
elements of an example list or record.
A comment may not split an item, so name # … : string is a syntax error.
Comments live in the header only. In the body # is ordinary text and does
not suppress interpolation — # ${title} renders as a Markdown heading with
${title} filled in. See Specification §2.2
for the normative rule.
Comments never reach the output, but they are not thrown away either: each one
survives as a positioned comment symbol in symbols(), so a formatter or IDE
can re-indent a header without losing them.
Example Blocks
Section titled “Example Blocks”example dbpedia "DBpedia — people & orgs" { service: <http://dbpedia.org/sparql> classes: [ foaf:Person, foaf:Organization ] limit: 10}An example <id> ["<description>"] { … } block (in the --- frontmatter,
alongside params) declares a named, validated set of sample values. They are
development/preview fixtures, not production defaults: render(context)
still requires real values, while previewExample(id) / a CLI renders with a
set so a query is runnable while you develop. An IDE lists blocks by id and
shows the description. Prefixed names resolve against the template’s PREFIX
declarations.
Detection
Section titled “Detection”A leading --- frontmatter header is a positive “this is a Triplate template”
marker, complementing the fail-fast guarantee (the body is invalid host syntax
until rendered).