| Armin Ronacher | ed98cac | 2008-05-07 08:42:11 +0200 | [diff] [blame] | 1 | .. _jinja-extensions: |
| 2 | |
| 3 | Extensions |
| 4 | ========== |
| 5 | |
| Armin Ronacher | ed98cac | 2008-05-07 08:42:11 +0200 | [diff] [blame] | 6 | Jinja2 supports extensions that can add extra filters, tests, globals or even |
| 7 | extend the parser. The main motivation of extensions is it to move often used |
| 8 | code into a reusable class like adding support for internationalization. |
| 9 | |
| 10 | |
| 11 | Adding Extensions |
| 12 | ----------------- |
| 13 | |
| 14 | Extensions are added to the Jinja2 environment at creation time. Once the |
| 15 | environment is created additional extensions cannot be added. To add an |
| 16 | extension pass a list of extension classes or import paths to the |
| 17 | `environment` parameter of the :class:`Environment` constructor. The following |
| 18 | example creates a Jinja2 environment with the i18n extension loaded:: |
| 19 | |
| Armin Ronacher | 09c002e | 2008-05-10 22:21:30 +0200 | [diff] [blame] | 20 | jinja_env = Environment(extensions=['jinja2.ext.i18n']) |
| Armin Ronacher | ed98cac | 2008-05-07 08:42:11 +0200 | [diff] [blame] | 21 | |
| 22 | |
| Armin Ronacher | ed98cac | 2008-05-07 08:42:11 +0200 | [diff] [blame] | 23 | .. _i18n-extension: |
| 24 | |
| Armin Ronacher | 023b5e9 | 2008-05-08 11:03:10 +0200 | [diff] [blame] | 25 | i18n Extension |
| 26 | -------------- |
| Armin Ronacher | ed98cac | 2008-05-07 08:42:11 +0200 | [diff] [blame] | 27 | |
| Armin Ronacher | 5d2733f | 2008-05-15 23:26:52 +0200 | [diff] [blame] | 28 | **Import name:** `jinja2.ext.i18n` |
| 29 | |
| Armin Ronacher | 023b5e9 | 2008-05-08 11:03:10 +0200 | [diff] [blame] | 30 | Jinja2 currently comes with one extension, the i18n extension. It can be |
| 31 | used in combination with `gettext`_ or `babel`_. If the i18n extension is |
| 32 | enabled Jinja2 provides a `trans` statement that marks the wrapped string as |
| 33 | translatable and calls `gettext`. |
| Armin Ronacher | ed98cac | 2008-05-07 08:42:11 +0200 | [diff] [blame] | 34 | |
| Armin Ronacher | 762079c | 2008-05-08 23:57:56 +0200 | [diff] [blame] | 35 | After enabling dummy `_` function that forwards calls to `gettext` is added |
| 36 | to the environment globals. An internationalized application then has to |
| 37 | provide at least an `gettext` and optoinally a `ngettext` function into the |
| 38 | namespace. Either globally or for each rendering. |
| 39 | |
| 40 | After enabling of the extension the environment provides the following |
| 41 | additional methods: |
| 42 | |
| 43 | .. method:: jinja2.Environment.install_gettext_translations(translations) |
| 44 | |
| 45 | Installs a translation globally for that environment. The tranlations |
| 46 | object provided must implement at least `ugettext` and `ungettext`. |
| 47 | The `gettext.NullTranslations` and `gettext.GNUTranslations` classes |
| 48 | as well as `Babel`_\s `Translations` class are supported. |
| 49 | |
| 50 | .. method:: jinja2.Environment.install_null_translations() |
| 51 | |
| 52 | Install dummy gettext functions. This is useful if you want to prepare |
| 53 | the application for internationalization but don't want to implement the |
| 54 | full internationalization system yet. |
| 55 | |
| 56 | .. method:: jinja2.Environment.uninstall_gettext_translations() |
| 57 | |
| 58 | Uninstall the translations again. |
| 59 | |
| 60 | .. method:: jinja2.Environment.extract_translations(source) |
| 61 | |
| 62 | Extract localizable strings from the given template node or source. |
| 63 | |
| 64 | For every string found this function yields a ``(lineno, function, |
| 65 | message)`` tuple, where: |
| 66 | |
| 67 | * `lineno` is the number of the line on which the string was found, |
| 68 | * `function` is the name of the `gettext` function used (if the |
| 69 | string was extracted from embedded Python code), and |
| 70 | * `message` is the string itself (a `unicode` object, or a tuple |
| 71 | of `unicode` objects for functions with multiple string arguments). |
| 72 | |
| 73 | If `Babel`_ is installed :ref:`the babel integration <babel-integration>` |
| 74 | can be used to extract strings for babel. |
| Armin Ronacher | ed98cac | 2008-05-07 08:42:11 +0200 | [diff] [blame] | 75 | |
| 76 | For a web application that is available in multiple languages but gives all |
| 77 | the users the same language (for example a multilingual forum software |
| 78 | installed for a French community) may load the translations once and add the |
| 79 | translation methods to the environment at environment generation time:: |
| 80 | |
| 81 | translations = get_gettext_translations() |
| Armin Ronacher | 2b22874 | 2008-05-18 20:29:32 +0200 | [diff] [blame] | 82 | env = Environment(extensions=['jinja2.ext.i18n']) |
| Armin Ronacher | 762079c | 2008-05-08 23:57:56 +0200 | [diff] [blame] | 83 | env.install_gettext_translations(translations) |
| Armin Ronacher | ed98cac | 2008-05-07 08:42:11 +0200 | [diff] [blame] | 84 | |
| 85 | The `get_gettext_translations` function would return the translator for the |
| Armin Ronacher | 762079c | 2008-05-08 23:57:56 +0200 | [diff] [blame] | 86 | current configuration. (For example by using `gettext.find`) |
| Armin Ronacher | ed98cac | 2008-05-07 08:42:11 +0200 | [diff] [blame] | 87 | |
| 88 | The usage of the `i18n` extension for template designers is covered as part |
| 89 | :ref:`of the template documentation <i18n-in-templates>`. |
| 90 | |
| Armin Ronacher | ed98cac | 2008-05-07 08:42:11 +0200 | [diff] [blame] | 91 | .. _gettext: http://docs.python.org/dev/library/gettext |
| Armin Ronacher | 762079c | 2008-05-08 23:57:56 +0200 | [diff] [blame] | 92 | .. _Babel: http://babel.edgewall.org/ |
| Armin Ronacher | ed98cac | 2008-05-07 08:42:11 +0200 | [diff] [blame] | 93 | |
| Armin Ronacher | 023b5e9 | 2008-05-08 11:03:10 +0200 | [diff] [blame] | 94 | |
| Armin Ronacher | 5d2733f | 2008-05-15 23:26:52 +0200 | [diff] [blame] | 95 | do |
| 96 | ~~ |
| 97 | |
| 98 | **Import name:** `jinja2.ext.do` |
| 99 | |
| 100 | The do aka expression-statement extension adds a simple `do` tag to the |
| 101 | template engine that works like a variable expression but ignores the |
| 102 | return value. |
| 103 | |
| 104 | |
| Armin Ronacher | ed98cac | 2008-05-07 08:42:11 +0200 | [diff] [blame] | 105 | .. _writing-extensions: |
| 106 | |
| 107 | Writing Extensions |
| 108 | ------------------ |
| 109 | |
| Armin Ronacher | 762079c | 2008-05-08 23:57:56 +0200 | [diff] [blame] | 110 | .. module:: jinja2.ext |
| 111 | |
| Armin Ronacher | 023b5e9 | 2008-05-08 11:03:10 +0200 | [diff] [blame] | 112 | By writing extensions you can add custom tags to Jinja2. This is a non trival |
| 113 | task and usually not needed as the default tags and expressions cover all |
| 114 | common use cases. The i18n extension is a good example of why extensions are |
| 115 | useful, another one would be fragment caching. |
| 116 | |
| Armin Ronacher | b9e7875 | 2008-05-10 23:36:28 +0200 | [diff] [blame] | 117 | When writing extensions you have to keep in mind that you are working with the |
| 118 | Jinja2 template compiler which does not validate the node tree you are possing |
| 119 | to it. If the AST is malformed you will get all kinds of compiler or runtime |
| 120 | errors that are horrible to debug. Always make sure you are using the nodes |
| 121 | you create correctly. The API documentation below shows which nodes exist and |
| 122 | how to use them. |
| 123 | |
| Armin Ronacher | 023b5e9 | 2008-05-08 11:03:10 +0200 | [diff] [blame] | 124 | Example Extension |
| 125 | ~~~~~~~~~~~~~~~~~ |
| 126 | |
| Armin Ronacher | 762079c | 2008-05-08 23:57:56 +0200 | [diff] [blame] | 127 | The following example implements a `cache` tag for Jinja2 by using the |
| 128 | `Werkzeug`_ caching contrib module: |
| Armin Ronacher | 023b5e9 | 2008-05-08 11:03:10 +0200 | [diff] [blame] | 129 | |
| 130 | .. literalinclude:: cache_extension.py |
| 131 | :language: python |
| 132 | |
| Armin Ronacher | 762079c | 2008-05-08 23:57:56 +0200 | [diff] [blame] | 133 | And here is how you use it in an environment:: |
| Armin Ronacher | 023b5e9 | 2008-05-08 11:03:10 +0200 | [diff] [blame] | 134 | |
| 135 | from jinja2 import Environment |
| 136 | from werkzeug.contrib.cache import SimpleCache |
| 137 | |
| Armin Ronacher | 762079c | 2008-05-08 23:57:56 +0200 | [diff] [blame] | 138 | env = Environment(extensions=[FragmentCacheExtension]) |
| 139 | env.fragment_cache = SimpleCache() |
| Armin Ronacher | 023b5e9 | 2008-05-08 11:03:10 +0200 | [diff] [blame] | 140 | |
| 141 | .. _Werkzeug: http://werkzeug.pocoo.org/ |
| 142 | |
| 143 | Extension API |
| 144 | ~~~~~~~~~~~~~ |
| 145 | |
| 146 | Extensions always have to extend the :class:`jinja2.ext.Extension` class: |
| 147 | |
| 148 | .. autoclass:: Extension |
| Armin Ronacher | 27069d7 | 2008-05-11 19:48:12 +0200 | [diff] [blame] | 149 | :members: parse, attr, call_method |
| Armin Ronacher | 023b5e9 | 2008-05-08 11:03:10 +0200 | [diff] [blame] | 150 | |
| 151 | .. attribute:: identifier |
| 152 | |
| 153 | The identifier of the extension. This is always the true import name |
| 154 | of the extension class and must not be changed. |
| 155 | |
| 156 | .. attribute:: tags |
| 157 | |
| 158 | If the extension implements custom tags this is a set of tag names |
| 159 | the extension is listening for. |
| 160 | |
| 161 | Parser API |
| 162 | ~~~~~~~~~~ |
| 163 | |
| 164 | The parser passed to :meth:`Extension.parse` provides ways to parse |
| 165 | expressions of different types. The following methods may be used by |
| 166 | extensions: |
| 167 | |
| 168 | .. autoclass:: jinja2.parser.Parser |
| Armin Ronacher | 09c002e | 2008-05-10 22:21:30 +0200 | [diff] [blame] | 169 | :members: parse_expression, parse_tuple, parse_assign_target, |
| Armin Ronacher | 7f15ef8 | 2008-05-16 09:11:39 +0200 | [diff] [blame] | 170 | parse_statements, free_identifier, fail |
| Armin Ronacher | 023b5e9 | 2008-05-08 11:03:10 +0200 | [diff] [blame] | 171 | |
| 172 | .. attribute:: filename |
| 173 | |
| 174 | The filename of the template the parser processes. This is **not** |
| Armin Ronacher | 67fdddf | 2008-05-16 09:27:51 +0200 | [diff] [blame] | 175 | the load name of the template. For the load name see :attr:`name`. |
| Armin Ronacher | 023b5e9 | 2008-05-08 11:03:10 +0200 | [diff] [blame] | 176 | For templates that were not loaded form the file system this is |
| 177 | `None`. |
| 178 | |
| Armin Ronacher | 67fdddf | 2008-05-16 09:27:51 +0200 | [diff] [blame] | 179 | .. attribute:: name |
| 180 | |
| 181 | The load name of the template. |
| 182 | |
| Armin Ronacher | 023b5e9 | 2008-05-08 11:03:10 +0200 | [diff] [blame] | 183 | .. attribute:: stream |
| 184 | |
| 185 | The current :class:`~jinja2.lexer.TokenStream` |
| 186 | |
| 187 | .. autoclass:: jinja2.lexer.TokenStream |
| Armin Ronacher | fdf9530 | 2008-05-11 22:20:51 +0200 | [diff] [blame] | 188 | :members: push, look, eos, skip, next, next_if, skip_if, expect |
| Armin Ronacher | 023b5e9 | 2008-05-08 11:03:10 +0200 | [diff] [blame] | 189 | |
| 190 | .. attribute:: current |
| 191 | |
| 192 | The current :class:`~jinja2.lexer.Token`. |
| 193 | |
| 194 | .. autoclass:: jinja2.lexer.Token |
| 195 | :members: test, test_any |
| 196 | |
| 197 | .. attribute:: lineno |
| 198 | |
| 199 | The line number of the token |
| 200 | |
| 201 | .. attribute:: type |
| 202 | |
| 203 | The type of the token. This string is interned so you may compare |
| 204 | it with arbitrary strings using the `is` operator. |
| 205 | |
| 206 | .. attribute:: value |
| 207 | |
| 208 | The value of the token. |
| 209 | |
| 210 | AST |
| 211 | ~~~ |
| 212 | |
| 213 | The AST (Abstract Syntax Tree) is used to represent a template after parsing. |
| 214 | It's build of nodes that the compiler then converts into executable Python |
| 215 | code objects. Extensions that provide custom statements can return nodes to |
| 216 | execute custom Python code. |
| 217 | |
| 218 | The list below describes all nodes that are currently available. The AST may |
| 219 | change between Jinja2 versions but will stay backwards compatible. |
| 220 | |
| 221 | For more information have a look at the repr of :meth:`jinja2.Environment.parse`. |
| 222 | |
| 223 | .. module:: jinja2.nodes |
| 224 | |
| 225 | .. jinjanodes:: |
| 226 | |
| 227 | .. autoexception:: Impossible |