| 1 | .. -*- mode: rst; encoding: utf-8 -*- |
| 2 | |
| 3 | ============================= |
| 4 | Genshi Text Template Language |
| 5 | ============================= |
| 6 | |
| 7 | In addition to the XML-based template language, Genshi provides a simple |
| 8 | text-based template language, intended for basic plain text generation needs. |
| 9 | The language is similar to the Django_ template language. |
| 10 | |
| 11 | This document describes the template language and will be most useful as |
| 12 | reference to those developing Genshi text templates. Templates are text files of |
| 13 | some kind that include processing directives_ that affect how the template is |
| 14 | rendered, and template expressions that are dynamically substituted by |
| 15 | variable data. |
| 16 | |
| 17 | See `Genshi Templating Basics <templates.html>`_ for general information on |
| 18 | embedding Python code in templates. |
| 19 | |
| 20 | .. note:: Actually, Genshi currently has two different syntaxes for text |
| 21 | templates languages: One implemented by the class ``OldTextTemplate`` |
| 22 | and another implemented by ``NewTextTemplate``. This documentation |
| 23 | concentrates on the latter, which is planned to completely replace the |
| 24 | older syntax. The older syntax is briefly described under legacy_. |
| 25 | |
| 26 | .. _django: http://www.djangoproject.com/ |
| 27 | |
| 28 | .. contents:: Contents |
| 29 | :depth: 3 |
| 30 | .. sectnum:: |
| 31 | |
| 32 | |
| 33 | .. _`directives`: |
| 34 | |
| 35 | ------------------- |
| 36 | Template Directives |
| 37 | ------------------- |
| 38 | |
| 39 | Directives are template commands enclosed by ``{% ... %}`` characters. They can |
| 40 | affect how the template is rendered in a number of ways: Genshi provides |
| 41 | directives for conditionals and looping, among others. |
| 42 | |
| 43 | Each directive must be terminated using an ``{% end %}`` marker. You can add |
| 44 | a string inside the ``{% end %}`` marker, for example to document which |
| 45 | directive is being closed, or even the expression associated with that |
| 46 | directive. Any text after ``end`` inside the delimiters is ignored, and |
| 47 | effectively treated as a comment. |
| 48 | |
| 49 | If you want to include a literal delimiter in the output, you need to escape it |
| 50 | by prepending a backslash character (``\``). |
| 51 | |
| 52 | |
| 53 | Conditional Sections |
| 54 | ==================== |
| 55 | |
| 56 | .. _`if`: |
| 57 | |
| 58 | ``{% if %}`` |
| 59 | ------------ |
| 60 | |
| 61 | The content is only rendered if the expression evaluates to a truth value: |
| 62 | |
| 63 | .. code-block:: genshitext |
| 64 | |
| 65 | {% if foo %} |
| 66 | ${bar} |
| 67 | {% end %} |
| 68 | |
| 69 | Given the data ``foo=True`` and ``bar='Hello'`` in the template context, this |
| 70 | would produce:: |
| 71 | |
| 72 | Hello |
| 73 | |
| 74 | |
| 75 | .. _`choose`: |
| 76 | .. _`when`: |
| 77 | .. _`otherwise`: |
| 78 | |
| 79 | ``{% choose %}`` |
| 80 | ---------------- |
| 81 | |
| 82 | The ``choose`` directive, in combination with the directives ``when`` and |
| 83 | ``otherwise``, provides advanced contional processing for rendering one of |
| 84 | several alternatives. The first matching ``when`` branch is rendered, or, if |
| 85 | no ``when`` branch matches, the ``otherwise`` branch is be rendered. |
| 86 | |
| 87 | If the ``choose`` directive has no argument the nested ``when`` directives will |
| 88 | be tested for truth: |
| 89 | |
| 90 | .. code-block:: genshitext |
| 91 | |
| 92 | The answer is: |
| 93 | {% choose %} |
| 94 | {% when 0 == 1 %}0{% end %} |
| 95 | {% when 1 == 1 %}1{% end %} |
| 96 | {% otherwise %}2{% end %} |
| 97 | {% end %} |
| 98 | |
| 99 | This would produce the following output:: |
| 100 | |
| 101 | The answer is: |
| 102 | 1 |
| 103 | |
| 104 | If the ``choose`` does have an argument, the nested ``when`` directives will |
| 105 | be tested for equality to the parent ``choose`` value: |
| 106 | |
| 107 | .. code-block:: genshitext |
| 108 | |
| 109 | The answer is: |
| 110 | {% choose 1 %}\ |
| 111 | {% when 0 %}0{% end %}\ |
| 112 | {% when 1 %}1{% end %}\ |
| 113 | {% otherwise %}2{% end %}\ |
| 114 | {% end %} |
| 115 | |
| 116 | This would produce the following output:: |
| 117 | |
| 118 | The answer is: |
| 119 | 1 |
| 120 | |
| 121 | |
| 122 | Looping |
| 123 | ======= |
| 124 | |
| 125 | .. _`for`: |
| 126 | |
| 127 | ``{% for %}`` |
| 128 | ------------- |
| 129 | |
| 130 | The content is repeated for every item in an iterable: |
| 131 | |
| 132 | .. code-block:: genshitext |
| 133 | |
| 134 | Your items: |
| 135 | {% for item in items %}\ |
| 136 | * ${item} |
| 137 | {% end %} |
| 138 | |
| 139 | Given ``items=[1, 2, 3]`` in the context data, this would produce:: |
| 140 | |
| 141 | Your items |
| 142 | * 1 |
| 143 | * 2 |
| 144 | * 3 |
| 145 | |
| 146 | |
| 147 | Snippet Reuse |
| 148 | ============= |
| 149 | |
| 150 | .. _`def`: |
| 151 | .. _`macros`: |
| 152 | |
| 153 | ``{% def %}`` |
| 154 | ------------- |
| 155 | |
| 156 | The ``def`` directive can be used to create macros, i.e. snippets of template |
| 157 | text that have a name and optionally some parameters, and that can be inserted |
| 158 | in other places: |
| 159 | |
| 160 | .. code-block:: genshitext |
| 161 | |
| 162 | {% def greeting(name) %} |
| 163 | Hello, ${name}! |
| 164 | {% end %} |
| 165 | ${greeting('world')} |
| 166 | ${greeting('everyone else')} |
| 167 | |
| 168 | The above would be rendered to:: |
| 169 | |
| 170 | Hello, world! |
| 171 | Hello, everyone else! |
| 172 | |
| 173 | If a macro doesn't require parameters, it can be defined without the |
| 174 | parenthesis. For example: |
| 175 | |
| 176 | .. code-block:: genshitext |
| 177 | |
| 178 | {% def greeting %} |
| 179 | Hello, world! |
| 180 | {% end %} |
| 181 | ${greeting()} |
| 182 | |
| 183 | The above would be rendered to:: |
| 184 | |
| 185 | Hello, world! |
| 186 | |
| 187 | |
| 188 | .. _includes: |
| 189 | .. _`include`: |
| 190 | |
| 191 | ``{% include %}`` |
| 192 | ----------------- |
| 193 | |
| 194 | To reuse common parts of template text across template files, you can include |
| 195 | other files using the ``include`` directive: |
| 196 | |
| 197 | .. code-block:: genshitext |
| 198 | |
| 199 | {% include base.txt %} |
| 200 | |
| 201 | Any content included this way is inserted into the generated output. The |
| 202 | included template sees the context data as it exists at the point of the |
| 203 | include. `Macros`_ in the included template are also available to the including |
| 204 | template after the point it was included. |
| 205 | |
| 206 | Include paths are relative to the filename of the template currently being |
| 207 | processed. So if the example above was in the file "``myapp/mail.txt``" |
| 208 | (relative to the template search path), the include directive would look for |
| 209 | the included file at "``myapp/base.txt``". You can also use Unix-style |
| 210 | relative paths, for example "``../base.txt``" to look in the parent directory. |
| 211 | |
| 212 | Just like other directives, the argument to the ``include`` directive accepts |
| 213 | any Python expression, so the path to the included template can be determined |
| 214 | dynamically: |
| 215 | |
| 216 | .. code-block:: genshitext |
| 217 | |
| 218 | {% include ${'%s.txt' % filename} %} |
| 219 | |
| 220 | Note that a ``TemplateNotFound`` exception is raised if an included file can't |
| 221 | be found. |
| 222 | |
| 223 | .. note:: The include directive for text templates was added in Genshi 0.5. |
| 224 | |
| 225 | |
| 226 | Variable Binding |
| 227 | ================ |
| 228 | |
| 229 | .. _`with`: |
| 230 | |
| 231 | ``{% with %}`` |
| 232 | -------------- |
| 233 | |
| 234 | The ``{% with %}`` directive lets you assign expressions to variables, which can |
| 235 | be used to make expressions inside the directive less verbose and more |
| 236 | efficient. For example, if you need use the expression ``author.posts`` more |
| 237 | than once, and that actually results in a database query, assigning the results |
| 238 | to a variable using this directive would probably help. |
| 239 | |
| 240 | For example: |
| 241 | |
| 242 | .. code-block:: genshitext |
| 243 | |
| 244 | Magic numbers! |
| 245 | {% with y=7; z=x+10 %} |
| 246 | $x $y $z |
| 247 | {% end %} |
| 248 | |
| 249 | Given ``x=42`` in the context data, this would produce:: |
| 250 | |
| 251 | Magic numbers! |
| 252 | 42 7 52 |
| 253 | |
| 254 | Note that if a variable of the same name already existed outside of the scope |
| 255 | of the ``with`` directive, it will **not** be overwritten. Instead, it will |
| 256 | have the same value it had prior to the ``with`` assignment. Effectively, |
| 257 | this means that variables are immutable in Genshi. |
| 258 | |
| 259 | |
| 260 | .. _whitespace: |
| 261 | |
| 262 | --------------------------- |
| 263 | White-space and Line Breaks |
| 264 | --------------------------- |
| 265 | |
| 266 | Note that space or line breaks around directives is never automatically removed. |
| 267 | Consider the following example: |
| 268 | |
| 269 | .. code-block:: genshitext |
| 270 | |
| 271 | {% for item in items %} |
| 272 | {% if item.visible %} |
| 273 | ${item} |
| 274 | {% end %} |
| 275 | {% end %} |
| 276 | |
| 277 | This will result in two empty lines above and beneath every item, plus the |
| 278 | spaces used for indentation. If you want to supress a line break, simply end |
| 279 | the line with a backslash: |
| 280 | |
| 281 | .. code-block:: genshitext |
| 282 | |
| 283 | {% for item in items %}\ |
| 284 | {% if item.visible %}\ |
| 285 | ${item} |
| 286 | {% end %}\ |
| 287 | {% end %}\ |
| 288 | |
| 289 | Now there would be no empty lines between the items in the output. But you still |
| 290 | get the spaces used for indentation, and because the line breaks are removed, |
| 291 | they actually continue and add up between lines. There are numerous ways to |
| 292 | control white-space in the output while keeping the template readable, such as |
| 293 | moving the indentation into the delimiters, or moving the end delimiter on the |
| 294 | next line, and so on. |
| 295 | |
| 296 | |
| 297 | .. _comments: |
| 298 | |
| 299 | -------- |
| 300 | Comments |
| 301 | -------- |
| 302 | |
| 303 | Parts in templates can be commented out using the delimiters ``{# ... #}``. |
| 304 | Any content in comments are removed from the output. |
| 305 | |
| 306 | .. code-block:: genshitext |
| 307 | |
| 308 | {# This won't end up in the output #} |
| 309 | This will. |
| 310 | |
| 311 | Just like directive delimiters, these can be escaped by prefixing with a |
| 312 | backslash. |
| 313 | |
| 314 | .. code-block:: genshitext |
| 315 | |
| 316 | \{# This *will* end up in the output, including delimiters #} |
| 317 | This too. |
| 318 | |
| 319 | |
| 320 | .. _legacy: |
| 321 | |
| 322 | --------------------------- |
| 323 | Legacy Text Template Syntax |
| 324 | --------------------------- |
| 325 | |
| 326 | The syntax for text templates was redesigned in version 0.5 of Genshi to make |
| 327 | the language more flexible and powerful. The older syntax is based on line |
| 328 | starting with dollar signs, similar to e.g. Cheetah_ or Velocity_. |
| 329 | |
| 330 | .. _cheetah: http://cheetahtemplate.org/ |
| 331 | .. _velocity: http://jakarta.apache.org/velocity/ |
| 332 | |
| 333 | A simple template using the old syntax looked like this: |
| 334 | |
| 335 | .. code-block:: genshitext |
| 336 | |
| 337 | Dear $name, |
| 338 | |
| 339 | We have the following items for you: |
| 340 | #for item in items |
| 341 | * $item |
| 342 | #end |
| 343 | |
| 344 | All the best, |
| 345 | Foobar |
| 346 | |
| 347 | Beyond the requirement of putting directives on separate lines prefixed with |
| 348 | dollar signs, the language itself is very similar to the new one. Except that |
| 349 | comments are lines that start with two ``#`` characters, and a line-break at the |
| 350 | end of a directive is removed automatically. |
| 351 | |
| 352 | .. note:: If you're using this old syntax, it is strongly recommended to |
| 353 | migrate to the new syntax. Simply replace any references to |
| 354 | ``TextTemplate`` by ``NewTextTemplate`` (and also change the |
| 355 | text templates, of course). On the other hand, if you want to stick |
| 356 | with the old syntax for a while longer, replace references to |
| 357 | ``TextTemplate`` by ``OldTextTemplate``; while ``TextTemplate`` is |
| 358 | still an alias for the old language at this point, that will change |
| 359 | in a future release. But also note that the old syntax may be |
| 360 | dropped entirely in a future release. |