SPARQL Query
Template SPARQL queries for backend applications and AI agents — typed, validated parameters instead of string concatenation. Query examples →

Triplate lets you write templates for RDF query and data languages, with typed parameters, loops, and conditionals. It’s designed for dynamically generating SPARQL queries in backend and AI applications, though it can also be used to generate other languages such as Markdown, HTML, or CSV.
What sets it apart from other templating languages is that all parameters are validated and escaped according to their declared RDF type, so rendered output is injection-safe by construction. Triplate’s syntax is deliberately invalid in the host language, so any unprocessed template parameters fail fast rather than silently producing malformed output.
SPARQL Query
Template SPARQL queries for backend applications and AI agents — typed, validated parameters instead of string concatenation. Query examples →
RDF Data
Stamp author and provenance metadata onto RDF artefacts, or generate synthetic Turtle/TriG datasets from plain records. Data examples →
The following example illustrates a SPARQL query and many of the unique features, such as the frontmatter, for loops and conditionals:
---params { service: iri classes: iri[] min 1 limit: int optional}example demo "DBpedia" { service: "http://dbpedia.org/sparql" classes: [ foaf:Person, foaf:Organization ] limit: 10}---PREFIX foaf: <http://xmlns.com/foaf/0.1/>SELECT ?s WHERE { SERVICE ${service} {{% for c in classes join "UNION" %} { ?s a ${c} }{% endfor %} }}{% if limit %}LIMIT ${limit}{% endif %}The example section named demo will be rendered with the following output:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>SELECT ?s WHERE { SERVICE <http://dbpedia.org/sparql> { { ?s a foaf:Person } UNION { ?s a foaf:Organization } }}LIMIT 10Zero dependencies
No runtime dependencies in any implementation — the TypeScript, Python and
Java cores are pure-language. (Python’s optional term type uses rdflib only
if you install the extra.)
Injection-safe by construction
Each value is validated and escaped per its declared RDF type. The only
unescaped path is the explicit raw type.
One typed header
A single --- … --- frontmatter declares every input — type, cardinality
(min/max), optionality — and is stripped from the output. The body stays
clean ${ } references.
Host-agnostic & fail-fast
The ${ }, $"…", $<…>, {% … %} syntax and the leading --- are invalid
in SPARQL/Turtle/TriG/N-Triples, so an unprocessed template can never run by
mistake.
Loops & conditionals
{% for %} with join, the ${...x} spread operator, and {% if %} with
type-directed conditions that make optional params usable.
Runnable examples
example blocks let an IDE preview and execute a query without hand-built
input — fixtures for development, never production defaults.
Three reference implementations
TypeScript, Python and Java — verified byte-identical by a shared conformance suite.
General-purpose engines treat SPARQL queries or RDF documents as opaque text; Triplate understands the RDF term model it emits.
| Triplate | Jinja2 | Mustache | Jena PSS¹ | |
|---|---|---|---|---|
RDF-typed params (iri, pname, literal(<dt>), …) |
● | ○ | ○ | ◐² |
| SPARQL/Turtle-aware escaping (injection-safe) | ● | ○³ | ○³ | ◐ |
| Whole context validated before rendering | ● | ○ | ○ | ○ |
| IRI minting — percent-encoded, validated absolute | ● | ○ | ○ | ○ |
@lang / ^^datatype literal construction |
● | ○ | ○ | ◐² |
Dynamic query shape (loops with join, if) |
● | ● | ◐ | ○ |
| Unrendered template fails fast at the endpoint | ● | ○ | ○ | — |
| Byte-identical across TypeScript, Python, Java | ● | ◐⁴ | ◐⁴ | ○ |
¹ Apache Jena ParameterizedSparqlString (Java-only, SPARQL-only).
² Code-side via Jena objects, not declared in the template.
³ Autoescaping targets HTML, not SPARQL.
⁴ Ports exist (Nunjucks, Jinjava, …) but diverge in semantics.