1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
//! # Trinja – HTML templating and Static Site Generator for RDF(S) resources
//!
//! Trinja is a library for converting arbitrary [RDF](https://www.w3.org/TR/rdf11-primer/)
//! data into HTML and also provides a *Static Site Generator* for building entire
//! web sites from RDF. It relies on [minijinja](https://docs.rs/minijinja/latest/minijinja/)
//! for templating and on the [Taganak SDK](https://sdk.taganak.net/) for RDF graph handling.
//!
//! ## Linking templates to RDF(S) resources
//!
//! Trinja loosely expects its input RDF data to follow [RDF Schema](https://www.w3.org/TR/rdf-schema/),
//! as it discovers HTML templates from the RDF types of resources. Consider the following RDF data:
//!
//! ```turtle
//! @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:
//!
//! ```turtle
//! @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](https://docs.rs/trinja/latest/trinja/).
//!
//! ## Defining static websites
//!
//! ### Data model
//!
//! 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.
//!
//! #### Site
//!
//! The `Site` class is the root of a static website. It defines global attributes
//! and the other parts of the website.
//!
//! ```turtle
//! @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.
//!
//! #### Template
//!
//! 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.
//!
//! ```turtle
//! @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`.
//!
//! #### Page
//!
//! A `Page` is a single page that will result in the generation of one HTML file.
//!
//! ```turtle
//! @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.
//!
//! #### Asset
//!
//! 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.
//!
//! ```turtle
//! @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](https://bulma.io/) 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:
//!
//! ```turtle
//! @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
//!
//! ### Example site
//!
//! An example site is available in the
//! [respository's example/ directory](https://codeberg.org/Taganak/trinja/src/branch/main/example).
//!
//! ## Library usage
//!
//! <div class="warning">
//!
//! Using trinja as a library in other code is not yet officially supported.
//!
//! </div>
//!
//! ## Command line usage
//!
//! 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.
//!
//! ### Rendering single resources
//!
//! ```shell
//! $ 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"
//! />
//! ```
//!
//! ### Building static sites
//!
//! ```shell
//! $ 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).
//!
//! ## Current limitations
//!
//! Trinja is in very early development. The following limitations hence apply:
//!
//! * API and vocabulary are unstable and will undergo changes before the first stable
//! release
//! * Relative paths generated for assets and page links are not sanitized (do not
//! handle untrusted source graphs)
//! * Most template errors will currently panic without a useful error message
use ;
use LanguageTag;
use Environment;
use ;
use Error;
;
;
/// Error cases for Trinja's operations