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
// SPDX-FileCopyrightText: 2026 Slatian <baschdel@disroot.org>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
//! # Writing Templates
//!
//! All templates use the [tera] templating engine and are stored in `templates/` inside the [template directory][crate::doc::template_directory]. (If you are following the examples this results in a `templates` directory inside a `templates` directory)
//!
//! A template for the `index` view and the `text` format with the `txt` extension would go in `templates/index.txt` for example.
//!
//! [tera syntax and reference](https://keats.github.io/tera/)
//!
//! # File names
//!
//! The templates follow the classic `{basename}{extension}` pattern where the `{basename}` is the view name from the [HumusView::get_template_name][crate::HumusView::get_template_name] function and `{extension}` is the [extension][crate::templating::FormatDescription::extension] from the [templates manifest][crate::doc::templates_manifest].
//!
//! All files directly in the templates directory are read as templates, this allows one to use files as shared macro libraries.
//!
//! Templates are only rendered where the [HumusApiFormat][crate::templating::HumusApiFormat] attached to the templating engine returns `None` for its [from_name][crate::templating::HumusApiFormat::from_name] function.
//!
//! # Provided values and functions
//!
//! In addition to the default functions provided by tera the following are provided.
//!
//! Values:
//! * `view` - The result of [HumusView::get_template_name][crate::HumusView::get_template_name].
//! * `format` - The format identifier from [HumusQuerySettings::get_format][crate::HumusQuerySettings::get_format].
//! * `lang` - The language from [HumusQuerySettings::get_preferred_language][crate::HumusQuerySettings::get_preferred_language] or the default languge from the language manifest.
//! * `language_manifest` - The data from the [LanguageManifest][crate::language::LanguageManifest] datastructure.
//! * `media_type` - The media type from the [FormatDescription][crate::templating::FormatDescription] from the template manifest. This was the `mimetype` field in versions `0.5` and earlier.
//! * `http_status` - The statuscode from [HumusView::get_status_code][crate::HumusView::get_status_code].
//! * `data` - contains the serde "serialized" data of the viw datastructure.
//! * `extra` - contains the data from the `extra.toml` file as is.
//!
//! The values are set in the [TemplatingEngine::render_view][crate::templating::TemplatingEngine::render_view] function.
//!
//! ## The `text` function
//!
//! The `text` function interfaces with the [LanguageEngine][crate::language::LanguageEngine] to fetch localized text.
//!
//! It is implemented in [TextFunction][crate::language::TextFunction].
//!
//! Arguments:
//! * `id` - The text id used as key in the translation files
//! * `lang` - Optional, explicitly set the language to use
//! * Other arguments are passed as variables to the translation message
//!
//! Example:
//! ```tera
//! {{ text(id="hello", custom_arg=123) }}
//! ```
//!
//! When `lang` is not set the langauge for the translation is sourced from a context outside the templates control that matches the initial value of the `lang` variable given to the template.
//!
//! ### The text function and HTML
//!
//! ⚠️ Be careful when generating HTML with the `text` function as fluent does not automatically escape text from placeables. ⚠️
//!
//! lib-humus provides the `ESCAPE_HTML(text)` function in fluent (same as the `escape_html` filter in tera) so you can sill have safe templates.
//!
//! Example of a fluent template that generates some HTML using `<q>`-tags and puts some untrusted text in it:
//!
//! You can't rely on tera doing the escaping because the `| safe` filter is needed to pass the desired HTML tags through. Wrapping the `$query` in `ESCAPE_HTML` makes sure that no HTML tags leak from the untrusted query.
//!
//! You should use a common suffix for all message ids that are expected to generate trusted HTML like `_html` in this example. This way checking for mistakes becomes way easier.
//!
//! In your tera template:
//! ```html
//! <p>{{ text(id="pretty_query_html", lang=lang, query=some_random_query ) | safe }}</p>
//! ```
//!
//! In your fluent `.flt` file:
//! ```flt
//! Your query was: <q>{ ESCAPE_HTML($query) }</q>
//! ```
//!
//! ## Functions and filters imported from `tera-contrib`
//!
//! Some functionality that previously was in tera directly moved to the [tera-contrib][tera_contrib] crate. `lib-humus` imports some of these by default:
//! * [`urlencode`][tera_contrib::urlencode::urlencode]
//! * [`urlencode_strict`][tera_contrib::urlencode::urlencode_strict]
//! * [`json_encode`][tera_contrib::json::json_encode]
//! * [`matching`][tera_contrib::regex::Matching]
//! * [`regex_replace`][tera_contrib::regex::RegexReplace]
//! * [`spaceless`][tera_contrib::regex::spaceless]
//! * [`striptags`][tera_contrib::regex::striptags]
//!
//! ## Application defined template context
//!
//! The view datastructure which provides the `data` field has a [hook function which it can use to register additional variables][crate::HumusView::initalize_template_context].
//!
//! The [TemplatingEngine][crate::templating::TemplatingEngine] also exposes its inner [Tera][tera::Tera] struct which can be used to register additional custom functions.
//!
//! You should have a look if the application you are writing templates for documents using those to provide additional functionality to the templates.