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