| [300] | 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. |
|---|
| [706] | 9 | The language is similar to the Django_ template language. |
|---|
| [300] | 10 | |
|---|
| 11 | This document describes the template language and will be most useful as |
|---|
| [534] | 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 |
|---|
| [300] | 15 | variable data. |
|---|
| 16 | |
|---|
| [534] | 17 | See `Genshi Templating Basics <templates.html>`_ for general information on |
|---|
| 18 | embedding Python code in templates. |
|---|
| [300] | 19 | |
|---|
| [706] | 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_. |
|---|
| [534] | 25 | |
|---|
| [706] | 26 | .. _django: http://www.djangoproject.com/ |
|---|
| 27 | |
|---|
| [300] | 28 | .. contents:: Contents |
|---|
| 29 | :depth: 3 |
|---|
| 30 | .. sectnum:: |
|---|
| 31 | |
|---|
| 32 | |
|---|
| 33 | .. _`directives`: |
|---|
| 34 | |
|---|
| 35 | ------------------- |
|---|
| 36 | Template Directives |
|---|
| 37 | ------------------- |
|---|
| 38 | |
|---|
| [706] | 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. |
|---|
| [300] | 42 | |
|---|
| [706] | 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. |
|---|
| [300] | 48 | |
|---|
| [706] | 49 | If you want to include a literal delimiter in the output, you need to escape it |
|---|
| 50 | by prepending a backslash character (``\``). |
|---|
| [300] | 51 | |
|---|
| [303] | 52 | |
|---|
| [300] | 53 | Conditional Sections |
|---|
| 54 | ==================== |
|---|
| 55 | |
|---|
| [706] | 56 | .. _`if`: |
|---|
| [300] | 57 | |
|---|
| [706] | 58 | ``{% if %}`` |
|---|
| 59 | ------------ |
|---|
| [300] | 60 | |
|---|
| [614] | 61 | The content is only rendered if the expression evaluates to a truth value: |
|---|
| [300] | 62 | |
|---|
| [614] | 63 | .. code-block:: genshitext |
|---|
| 64 | |
|---|
| [706] | 65 | {% if foo %} |
|---|
| [300] | 66 | ${bar} |
|---|
| [706] | 67 | {% end %} |
|---|
| [300] | 68 | |
|---|
| 69 | Given the data ``foo=True`` and ``bar='Hello'`` in the template context, this |
|---|
| 70 | would produce:: |
|---|
| 71 | |
|---|
| 72 | Hello |
|---|
| 73 | |
|---|
| 74 | |
|---|
| [706] | 75 | .. _`choose`: |
|---|
| 76 | .. _`when`: |
|---|
| 77 | .. _`otherwise`: |
|---|
| [300] | 78 | |
|---|
| [706] | 79 | ``{% choose %}`` |
|---|
| 80 | ---------------- |
|---|
| [300] | 81 | |
|---|
| [706] | 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. |
|---|
| [300] | 86 | |
|---|
| [706] | 87 | If the ``choose`` directive has no argument the nested ``when`` directives will |
|---|
| 88 | be tested for truth: |
|---|
| [300] | 89 | |
|---|
| [614] | 90 | .. code-block:: genshitext |
|---|
| 91 | |
|---|
| [300] | 92 | The answer is: |
|---|
| [706] | 93 | {% choose %} |
|---|
| 94 | {% when 0 == 1 %}0{% end %} |
|---|
| 95 | {% when 1 == 1 %}1{% end %} |
|---|
| 96 | {% otherwise %}2{% end %} |
|---|
| 97 | {% end %} |
|---|
| [300] | 98 | |
|---|
| 99 | This would produce the following output:: |
|---|
| 100 | |
|---|
| 101 | The answer is: |
|---|
| [706] | 102 | 1 |
|---|
| [300] | 103 | |
|---|
| [706] | 104 | If the ``choose`` does have an argument, the nested ``when`` directives will |
|---|
| 105 | be tested for equality to the parent ``choose`` value: |
|---|
| [300] | 106 | |
|---|
| [614] | 107 | .. code-block:: genshitext |
|---|
| 108 | |
|---|
| [300] | 109 | The answer is: |
|---|
| [706] | 110 | {% choose 1 %}\ |
|---|
| 111 | {% when 0 %}0{% end %}\ |
|---|
| 112 | {% when 1 %}1{% end %}\ |
|---|
| 113 | {% otherwise %}2{% end %}\ |
|---|
| 114 | {% end %} |
|---|
| [300] | 115 | |
|---|
| 116 | This would produce the following output:: |
|---|
| 117 | |
|---|
| 118 | The answer is: |
|---|
| 119 | 1 |
|---|
| 120 | |
|---|
| 121 | |
|---|
| 122 | Looping |
|---|
| 123 | ======= |
|---|
| 124 | |
|---|
| [706] | 125 | .. _`for`: |
|---|
| [300] | 126 | |
|---|
| [706] | 127 | ``{% for %}`` |
|---|
| 128 | ------------- |
|---|
| [300] | 129 | |
|---|
| [614] | 130 | The content is repeated for every item in an iterable: |
|---|
| [300] | 131 | |
|---|
| [614] | 132 | .. code-block:: genshitext |
|---|
| 133 | |
|---|
| [300] | 134 | Your items: |
|---|
| [706] | 135 | {% for item in items %}\ |
|---|
| [300] | 136 | * ${item} |
|---|
| [706] | 137 | {% end %} |
|---|
| [300] | 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 | |
|---|
| [706] | 150 | .. _`def`: |
|---|
| [300] | 151 | .. _`macros`: |
|---|
| 152 | |
|---|
| [706] | 153 | ``{% def %}`` |
|---|
| 154 | ------------- |
|---|
| [300] | 155 | |
|---|
| [706] | 156 | The ``def`` directive can be used to create macros, i.e. snippets of template |
|---|
| [300] | 157 | text that have a name and optionally some parameters, and that can be inserted |
|---|
| [614] | 158 | in other places: |
|---|
| [300] | 159 | |
|---|
| [614] | 160 | .. code-block:: genshitext |
|---|
| 161 | |
|---|
| [706] | 162 | {% def greeting(name) %} |
|---|
| [300] | 163 | Hello, ${name}! |
|---|
| [706] | 164 | {% end %} |
|---|
| [300] | 165 | ${greeting('world')} |
|---|
| 166 | ${greeting('everyone else')} |
|---|
| 167 | |
|---|
| 168 | The above would be rendered to:: |
|---|
| 169 | |
|---|
| 170 | Hello, world! |
|---|
| 171 | Hello, everyone else! |
|---|
| 172 | |
|---|
| [706] | 173 | If a macro doesn't require parameters, it can be defined without the |
|---|
| 174 | parenthesis. For example: |
|---|
| [300] | 175 | |
|---|
| [614] | 176 | .. code-block:: genshitext |
|---|
| 177 | |
|---|
| [706] | 178 | {% def greeting %} |
|---|
| [300] | 179 | Hello, world! |
|---|
| [706] | 180 | {% end %} |
|---|
| 181 | ${greeting()} |
|---|
| [300] | 182 | |
|---|
| 183 | The above would be rendered to:: |
|---|
| 184 | |
|---|
| 185 | Hello, world! |
|---|
| 186 | |
|---|
| 187 | |
|---|
| [577] | 188 | .. _includes: |
|---|
| [706] | 189 | .. _`include`: |
|---|
| [577] | 190 | |
|---|
| [706] | 191 | ``{% include %}`` |
|---|
| 192 | ----------------- |
|---|
| [577] | 193 | |
|---|
| 194 | To reuse common parts of template text across template files, you can include |
|---|
| [706] | 195 | other files using the ``include`` directive: |
|---|
| [577] | 196 | |
|---|
| [614] | 197 | .. code-block:: genshitext |
|---|
| 198 | |
|---|
| [706] | 199 | {% include base.txt %} |
|---|
| [577] | 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 | |
|---|
| [706] | 212 | Just like other directives, the argument to the ``include`` directive accepts |
|---|
| [577] | 213 | any Python expression, so the path to the included template can be determined |
|---|
| [614] | 214 | dynamically: |
|---|
| [577] | 215 | |
|---|
| [614] | 216 | .. code-block:: genshitext |
|---|
| 217 | |
|---|
| [809] | 218 | {% include ${'%s.txt' % filename} %} |
|---|
| [577] | 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 | |
|---|
| [300] | 226 | Variable Binding |
|---|
| 227 | ================ |
|---|
| 228 | |
|---|
| [706] | 229 | .. _`with`: |
|---|
| [300] | 230 | |
|---|
| [706] | 231 | ``{% with %}`` |
|---|
| 232 | -------------- |
|---|
| [300] | 233 | |
|---|
| [706] | 234 | The ``{% with %}`` directive lets you assign expressions to variables, which can |
|---|
| [300] | 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 | |
|---|
| [614] | 240 | For example: |
|---|
| [300] | 241 | |
|---|
| [614] | 242 | .. code-block:: genshitext |
|---|
| 243 | |
|---|
| [300] | 244 | Magic numbers! |
|---|
| [706] | 245 | {% with y=7; z=x+10 %} |
|---|
| [300] | 246 | $x $y $z |
|---|
| [706] | 247 | {% end %} |
|---|
| [300] | 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 |
|---|
| [706] | 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, |
|---|
| [300] | 257 | this means that variables are immutable in Genshi. |
|---|
| 258 | |
|---|
| 259 | |
|---|
| [706] | 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 | |
|---|
| [300] | 297 | .. _comments: |
|---|
| 298 | |
|---|
| 299 | -------- |
|---|
| 300 | Comments |
|---|
| 301 | -------- |
|---|
| 302 | |
|---|
| [706] | 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 |
|---|
| [300] | 312 | backslash. |
|---|
| [706] | 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 | |
|---|
| [809] | 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 |
|---|
| [706] | 357 | ``TextTemplate`` by ``OldTextTemplate``; while ``TextTemplate`` is |
|---|
| 358 | still an alias for the old language at this point, that will change |
|---|
| [809] | 359 | in a future release. But also note that the old syntax may be |
|---|
| 360 | dropped entirely in a future release. |
|---|