188 | | ==== Text extraction from Javascript code ==== |
189 | | |
190 | | |
| 187 | ==== Text extraction from Javascript code ==== #Javascript |
| 188 | |
| 189 | Adding support for translating the marked strings in the Javascript code is a bit more involved, but if you made it to this point, that shouldn't scare you away... |
| 190 | |
| 191 | We currently support only statically deployed Javascript files, which means they can't be translated like template files on the server, but that the translation has to happen dynamically on the client side. To this end, we want to send an additional `.js` file containing a dictionary of the messages that have to be translated, and only those. In order to clearly identify which strings have to be present in this dictionary, we'll extract the messages marked for translation (the usual `_(...)` ways) from the Javascript code into a dedicated catalog template, and from there, we'll create dedicated catalogs for each locale. In the end, the translations present in each compiled catalog will be extracted and placed into a `.js` file containing the messages dictionary and some setup code. |
| 192 | |
| 193 | The first change is to use `get_l10n_js_cmdclass` in lieu of `get_l10n_cmdclass`. The former adds a few more setup commands for extracting messages strings from Javascript `.js` files and `<script type="text/javascript">` snippets in `.html` files, initialization and updating of dedicated catalog files, and finally compiling that catalog and creating a `.js` file containing the dictionary of strings, ready to be used by the `babel.js` support code already present in Trac pages. |
| 194 | |
| 195 | The change to `setup.py` looks like this: |
| 196 | {{{#!diff |
| 197 | diff -u a/setup.py b/setup.py |
| 198 | --- a/setup.py |
| 199 | +++ b/setup.py |
| 200 | @@ -5,8 +5,8 @@ from setuptools import setup |
| 201 | extra = {} |
| 202 | |
| 203 | -from trac.util.dist import get_l10n_cmdclass |
| 204 | -cmdclass = get_l10n_cmdclass() |
| 205 | +from trac.util.dist import get_l10n_js_cmdclass |
| 206 | +cmdclass = get_l10n_js_cmdclass() |
| 207 | if cmdclass: |
| 208 | extra['cmdclass'] = cmdclass |
| 209 | extra['message_extractors'] = { |
| 210 | }}} |
| 211 | |
| 212 | That was the easiest part. |
| 213 | |
| 214 | Now, as you need to actually send that `.js` file containing the messages dictionary, call `add_script()` as appropriate in the `process_request()` method from your module: |
| 215 | |
| 216 | {{{#!diff |
| 217 | --- a/<path>/api.py |
| 218 | +++ b/<path>/api.py |
| 219 | @@ -243,6 +243,8 @@ class FooTracPlugin(Component): |
| 220 | builds = self._extract_builds(self._get_info(start, stop)) |
| 221 | data = {'builds': list(builds)} |
| 222 | add_script(req, '<path>/hudsontrac.js') |
| 223 | + if req.locale is not None: |
| 224 | + add_script(req, '<path>/foo/%s.js' % req.locale) |
| 225 | add_stylesheet(req, '<path>/foo.css') |
| 226 | return 'foo-build.html', data, None |
| 227 | |
| 228 | }}} |
| 229 | |
| 230 | Now, you need to expand the `setup.cfg` file with the configuration that the new `cmdclass` dedicated to Javascript translation need. Those classes all end with an `_js` suffix. |
| 231 | |
| 232 | {{{#!ini |
| 233 | [extract_messages_js] |
| 234 | add_comments = TRANSLATOR: |
| 235 | copyright_holder = <Your Name> |
| 236 | msgid_bugs_address = <Your E-Mail> |
| 237 | output_file = <path>/locale/messages-js.pot |
| 238 | keywords = _ ngettext:1,2 N_ |
| 239 | mapping_file = messages-js.cfg |
| 240 | |
| 241 | [init_catalog_js] |
| 242 | domain = foo-js |
| 243 | input_file = <path>/locale/messages-js.pot |
| 244 | output_dir = <path>/locale |
| 245 | |
| 246 | [compile_catalog_js] |
| 247 | domain = foo-js |
| 248 | directory = <path>/locale |
| 249 | |
| 250 | [update_catalog_js] |
| 251 | domain = foo-js |
| 252 | input_file = <path>/locale/messages-js.pot |
| 253 | output_dir = <path>/locale |
| 254 | |
| 255 | [generate_messages_js] |
| 256 | domain = foo-js |
| 257 | input_dir = <path>/locale |
| 258 | output_dir = <path>/htdocs/foo |
| 259 | }}} |
| 260 | |
| 261 | As before, replace `<path>` with what's appropriate for your plugin. Note that the domain name is now `foo-js`, not just `foo` as before. This is necessary as we want to have only the strings actually needed Javascript to be stored in the `.js` file containing the messages dictionary. |
| 262 | |
| 263 | We're nearly done yet... noticed the `mapping_file = messages-js.cfg` line? |
| 264 | We need to configure separately how to do the extraction for this `messages-js.pot` catalog template. |
| 265 | The `messages-js.cfg` file has the following content: |
| 266 | {{{#!ini |
| 267 | # mapping file for extracting messages from javascript files into |
| 268 | # <path>/locale/messages-js.pot (see setup.cfg) |
| 269 | [javascript: **.js] |
| 270 | |
| 271 | [extractors] |
| 272 | javascript_script = trac.util.dist:extract_javascript_script |
| 273 | |
| 274 | [javascript_script: **.html] |
| 275 | }}} |
| 276 | |
| 277 | Bonus points for anyone who will manage to //simplify// a bit this procedure ;-) |