| Crates.io | trinja |
| lib.rs | trinja |
| version | 0.6.1 |
| created_at | 2025-06-17 22:48:04.974157+00 |
| updated_at | 2025-08-12 15:37:06.522118+00 |
| description | HTML templating / SSG for RDF(S) resources |
| homepage | https://trinja.taganak.net/ |
| repository | https://codeberg.org/Taganak/trinja |
| max_upload_size | |
| id | 1716369 |
| size | 207,563 |
Trinja is a library for converting arbitrary RDF data into HTML and also provides a Static Site Generator for building entire web sites from RDF. It relies on minijinja for templating and on the Taganak SDK for RDF graph handling.
Trinja loosely expects its input RDF data to follow RDF Schema, as it discovers HTML templates from the RDF types of resources. Consider the following RDF data:
@prefix ex: <https://sdk.taganak.net/vocab/examples/> .
<#leonardo> a ex:Turtle ;
ex:name "Leonardo" ;
ex:image "https://static.wikia.nocookie.net/tmnt/images/8/8b/Leonardo.png" .
<#raphael> a ex:Turtle ;
ex:name "Raphael" ;
ex:image "https://static.wikia.nocookie.net/tmnt/images/5/5a/Raphael.png" .
Linking a minijinja template to these resources can be done in several ways:
@prefix trinja: <https://trinja.taganak.net/vocab/> .
@prefix ex: <https://sdk.taganak.net/vocab/examples/> .
# Linking directly to one resource
<#leonardo> trinja:template """
<img
src="{{ this["<https://sdk.taganak.net/vocab/examples/image>"] }}"
alt="{{ this["<https://sdk.taganak.net/vocab/examples/name>"] }}"
/>
"""^^trinja:minijinja .
# Linking directly to the RDF(S) type
ex:Turtle trinja:genericTemplate """
<img
src="{{ this["<https://sdk.taganak.net/vocab/examples/image>"] }}"
alt="{{ this["<https://sdk.taganak.net/vocab/examples/name>"] }}"
/>
"""^^trinja:minijinja .
For more alternatives and detailed documentation, see the crate docs.
Static websites can be defined using Trinja's custom vocabulary. While sites can consist of arbitrary linked data under arbitrary IRIs, designing an IRI scheme that maps nicely to the resulting website significantly simplifies the model.
The Site class is the root of a static website. It defines global attributes
and the other parts of the website.
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix trinja: <https://trinja.taganak.net/vocab/> .
<> a trinja:Site ;
dc:title "My website" ;
trinja:template <#template> .
The trinja:template predicate points to a re-usable template that will be both
the default template for all pages that don't define their own template, and be
available under the special name site in template to extend.
A Template resource defines a re-usable template. Templates can be referred to
by their IRI in other templates, e.g. using minijinja's extend or import
statements.
@prefix trinja: <https://trinja.taganak.net/vocab/> .
<#template> a trinja:Template ;
trinja:template """
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}{{ site["<http://purl.org/dc/elements/1.1/title>"] }}{% endblock %}</title>
</head>
</html>
"""^^trinja:minijinja .
Note how the site variable is used to reference the resource defining the Site.
A Page is a single page that will result in the generation of one HTML file.
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix trinja: <https://trinja.taganak.net/vocab/> .
<example> a trinja:Page ;
dc:title "Example page" ;
trinja:template """
{% extends "default" %}
{% block title %}{{ this["<http://purl.org/dc/elements/1.1/title>"] }}{% block title %}
"""^^trinja:minijinja .
Note how the this variable is used to refer to the currently rendered resource,
just like in simple HTML fragments described above.
Pages can be added to a Site using the trinja:page predicate. If the predicate
is omitted, then all trinja:Page resources on the graph will be included.
Just like pages, assets will be added to the vuilt static site, but they are not built using templates, but instead copied from outside the graph.
@prefix trinja: <https://trinja.taganak.net/vocab/> .
<assets/bulma.min.css> a trinja:Asset ;
trinja:source <https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css> .
When building the site, Bulma CSS will be downloaded and added to the output directory.
To use assets in templates, the rdf_asset function is available. It resolves
an IRI on the input graph into a relative URL in the output directory:
@prefix trinja: <https://trinja.taganak.net/vocab/> .
<some/path/to/a/page> a trinja:Page ;
trinja:template """
<link rel="{{ rdf_asset("<../../../bulma>") }}" />
"""^^trinja:minijinja .
<bulma> a trinja:Asset ;
trinja:source <https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css> ;
trinja:output "style/bulma.min.css".
This template will correctly insert a relative link to the output CSS file.
Note that the ../../../ in the rdf_asset IRI reference does not reflect
the relative location in the output directory, but on the input graph.w
An example site is available in the respository's example/ directory.
Using trinja as a library in other code is not yet officially supported.
The trinja command can be used to render individual RDF resources as HTML
fragments or to build entire static websites from linked data.
All commands access a single RDF source as a graph. To facilitate working with
local directories, especially when using Trinja as SSG, the default graph uses
the custom file+glob graph source provided by Taganak, using the pattern
**/*.ttl starting from the current directory.
$ trinja -q "file://$PWD/example.ttl" resource "file://$PWD/example.ttl#leonardo" render
<img
src="https://static.wikia.nocookie.net/tmnt/images/8/8b/Leonardo.png"
alt="Leonardo"
/>
$ cargo install trinja
$ trinja site build
2025-06-17T19:47:50.904719Z INFO trinja: Using default source IRI file+glob:///home/nik/Taganak/trinja/example/**/*.ttl
2025-06-17T19:47:50.917814Z INFO trinja: Using default site base IRI file:///home/nik/Taganak/trinja/example/
2025-06-17T19:47:50.918969Z INFO trinja::site: Building site, starting from file:///home/nik/Taganak/trinja/example/, to /home/nik/Taganak/trinja/example/output
2025-06-17T19:47:50.919035Z WARN trinja::site: Assets not defined on site; searching all trinja:Asset on graph
2025-06-17T19:47:50.919929Z INFO trinja::site: Storing asset from https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css into /home/nik/Taganak/trinja/example/output/style/bulma.min.css
2025-06-17T19:47:51.265031Z INFO trinja::site: Storing asset from https://static.wikia.nocookie.net/tmnt/images/9/94/Michelangelo.png into /home/nik/Taganak/trinja/example/output/michelangelo.png
2025-06-17T19:47:51.506999Z INFO trinja::site: Storing asset from https://static.wikia.nocookie.net/tmnt/images/8/8b/Leonardo.png into /home/nik/Taganak/trinja/example/output/leonardo.png
2025-06-17T19:47:51.855151Z INFO trinja::site: Storing asset from https://static.wikia.nocookie.net/tmnt/images/5/5a/Raphael.png into /home/nik/Taganak/trinja/example/output/raphael.png
2025-06-17T19:47:52.093873Z INFO trinja::site: Storing asset from https://static.wikia.nocookie.net/tmnt/images/e/e7/Donatello.png into /home/nik/Taganak/trinja/example/output/donatello.png
2025-06-17T19:47:52.369318Z WARN trinja::site: Pages not defined on site; searching all trinja:Page on graph
2025-06-17T19:47:52.370115Z INFO trinja::site: Rendering page <file:///home/nik/Taganak/trinja/example/turtles> into /home/nik/Taganak/trinja/example/output/turtles.html
2025-06-17T19:47:52.380577Z INFO trinja::site: Rendering page <file:///home/nik/Taganak/trinja/example/#frontpage> into /home/nik/Taganak/trinja/example/output/index.html
$ tree ./output/
./output/
├── donatello.png
├── index.html
├── leonardo.png
├── michelangelo.png
├── raphael.png
├── style
│ └── bulma.min.css
└── turtles.html
Note how the assets have been placed in the desired output locations (and correctly been linked in the HTML output).
Trinja is in very early development. The following limitations hence apply: