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