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