| 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 | |