1 | //! Documentation of TinyTemplate's template syntax. |
2 | //! |
3 | //! ### Context Types |
4 | //! |
5 | //! TinyTemplate uses `serde_json`'s Value structure to represent the context. Therefore, any |
6 | //! `Serializable` structure can be used as a context. All values in such structures are mapped to |
7 | //! their JSON representations - booleans, numbers, strings, arrays, objects and nulls. |
8 | //! |
9 | //! ### Values |
10 | //! |
11 | //! Template values are marked with `{...}`. For example, this will look up the "name" field in |
12 | //! the context structure and insert it into the rendered string: |
13 | //! |
14 | //! ```text |
15 | //! Hello, {name}, how are you? |
16 | //! ``` |
17 | //! |
18 | //! Optionally, a value formatter may be provided. One formatter, "unescaped", is provided by |
19 | //! default. Any other formatters must be registered with the |
20 | //! [`TinyTemplate.add_formatter`](../struct.TinyTemplate.html#method.add_formatter) |
21 | //! function prior to rendering or an error will be generated. This will call the formatter function |
22 | //! registered as "percent_formatter" with the value of the "percentage" field: |
23 | //! |
24 | //! ```text |
25 | //! Give it {percentage | percent_formatter}! |
26 | //! ``` |
27 | //! |
28 | //! The value may be a dotted path through a hierarchy of context objects. This will look up the |
29 | //! "friend" field in the context structure, then substitute the "name" field from the "friend" |
30 | //! object. |
31 | //! |
32 | //! ```text |
33 | //! And hello to {friend.name} as well! |
34 | //! ``` |
35 | //! |
36 | //! Additionally, you may use the `@root` keyword to refer to the root object of your context. |
37 | //! Since TinyTemplate can't normally print complex context objects, this is only useful if the |
38 | //! context is a simple object like an integer or string. |
39 | //! |
40 | //! ### Conditionals |
41 | //! |
42 | //! TinyTemplate blocks are marked with `{{...}}` - double-braces where values are single-braces. |
43 | //! |
44 | //! Conditionals are denoted by "{{ if path }}...{{ else }}...{{ endif }}". The Else block is |
45 | //! optional. Else-if is not currently supported. If "path" evaluates to a truthy expression |
46 | //! (true if boolean, non-zero if numeric, non-empty for strings and arrays, and non-null for |
47 | //! objects) then the section of the template between "if" and "else" is evaluated, otherwise the |
48 | //! section between "else" and "endif" (if present) is evaluated. |
49 | //! |
50 | //! ```text |
51 | //! {{ if user.is_birthday }} |
52 | //! Happy Birthday! |
53 | //! {{ else }} |
54 | //! Have a nice day! |
55 | //! {{ endif }} |
56 | //! ``` |
57 | //! |
58 | //! The condition can be negated by using "{{ if not path }}": |
59 | //! |
60 | //! ```text |
61 | //! {{ if not user.is_birthday }} |
62 | //! Have a nice day! |
63 | //! {{ else }} |
64 | //! Happy Birthday! |
65 | //! {{ endif }} |
66 | //! ``` |
67 | //! |
68 | //! If desired, the `@root` keyword can be used to branch on the root context object. |
69 | //! |
70 | //! ### Loops |
71 | //! |
72 | //! TinyTemplate supports iterating over the values of arrays. Only arrays are supported. Loops |
73 | //! are denoted by "{{ for value_name in value.path }}...{{ endfor }}". The section of the template between |
74 | //! the two tags will be executed once for each value in the array denoted by "value.path". |
75 | //! |
76 | //! ```text |
77 | //! Hello to {{ for name in guests }} |
78 | //! {name} |
79 | //! {{ endfor }} |
80 | //! ``` |
81 | //! |
82 | //! If the iteration value chosen in the "for" tag is the same as that of a regular context value, |
83 | //! the name in the tag will shadow the context value for the scope of the loop. For nested loops, |
84 | //! inner loops will shadow the values of outer loops. |
85 | //! |
86 | //! ```text |
87 | //! {{ for person in guests }} |
88 | //! Hello to {person}{{ for person in person.friends }} and your friend {person}{{ endfor }} |
89 | //! {{ endfor }} |
90 | //! ``` |
91 | //! |
92 | //! There are three special values which are available within a loop: |
93 | //! |
94 | //! * `@index` - zero-based index of the current value within the array. |
95 | //! * `@first` - true if this is the first iteration of the loop, otherwise false. |
96 | //! * `@last` - true if this is the last iteration of the loop, otherwise false. |
97 | //! |
98 | //! ```text |
99 | //! Hello to {{ for name in guests -}} |
100 | //! { @index }. {name}, |
101 | //! {{- endfor }} |
102 | //! ``` |
103 | //! |
104 | //! |
105 | //! In case of nested loops, these values refer to the innermost loop which contains them. |
106 | //! |
107 | //! If the root context object is an array, the `@root` keyword can be used to iterate over the |
108 | //! root object. |
109 | //! |
110 | //! ### With Blocks |
111 | //! |
112 | //! Templates can use with blocks to partially shadows the outer context, the same way that |
113 | //! for-loops do. These are formed like so: |
114 | //! |
115 | //! "{{ with path.to.value as name }}..{{ endwith }}"" |
116 | //! |
117 | //! For example: |
118 | //! |
119 | //! ```text |
120 | //! {{ with person.spouse as s }} |
121 | //! Hello { s.name }! |
122 | //! {{ endwith }} |
123 | //! ``` |
124 | //! |
125 | //! This looks up "person.spouse" and adds that to the context as "s" within the block. Only the |
126 | //! name "s" is shadowed within the with block and otherwise the outer context is still accessible. |
127 | //! |
128 | //! ### Trimming Whitespace |
129 | //! |
130 | //! If a block tag, comment or value tag includes a "-" character at the start, the trailing |
131 | //! whitespace of the previous text section will be skipped in the output. Likewise, if the tag |
132 | //! ends with a "-", the leading whitespace of the following text will be skipped. |
133 | //! |
134 | //! ```text |
135 | //! Hello { friend.name -} |
136 | //! , how are you? |
137 | //! |
138 | //! {{- if status.good }} I am fine. {{- endif }} |
139 | //! ``` |
140 | //! |
141 | //! This will print "Hello friend, how are you? I am fine." without the newlines or extra spaces. |
142 | //! |
143 | //! ### Calling other Templates |
144 | //! |
145 | //! Templates may call other templates by name. The other template must have been registered using |
146 | //! the [`TinyTemplate.add_template`](../struct.TinyTemplate.html#method.add_template) function |
147 | //! before rendering or an error will be generated. This is done with the "call" tag: |
148 | //! |
149 | //! "{{ call template_name with path.to.context }}" |
150 | //! |
151 | //! The call tag has no closing tag. This will look up the "path.to.context" path in the current |
152 | //! context, then render the "template_name" template using the value at that path as the context |
153 | //! for the other template. The string produced by the called template is then inserted into the |
154 | //! output from the calling template. This can be used for a limited form of template code reuse. |
155 | //! |
156 | //! ### Comments |
157 | //! |
158 | //! Comments in the templates are denoted by "{# comment text #}". Comments will be skipped when |
159 | //! rendering the template, though whitespace adjacent to comments will not be stripped unless the |
160 | //! "-" is added. For example: |
161 | //! |
162 | //! ```text |
163 | //! Hello |
164 | //! |
165 | //! {#- This is a comment #} world! |
166 | //! ``` |
167 | //! |
168 | //! This will print "Hello world!". |
169 | //! |
170 | //! ### Escaping Curly Braces |
171 | //! |
172 | //! If your template contains opening curly-braces (`{`), they must be escaped using a leading `\` |
173 | //! character. For example: |
174 | //! |
175 | //! ```text |
176 | //! h2 \{ |
177 | //! font-size: {fontsize}; |
178 | //! } |
179 | //! ``` |
180 | //! |
181 | //! If using a string literal in rust source code, the `\` itself must be escaped, producing `\\{`. |
182 | //! |
183 | |
184 | // There's nothing here, this module is solely for documentation. |
185 | |