Mercurial > p > roundup > code
comparison doc/developers.txt @ 2353:bf3f75134e03
i18n notes brought here from ../I18N_PROGRESS.txt
added "Translating Messages" and "Compiling Message Catalogs" sections
| author | Alexander Smishlajev <a1s@users.sourceforge.net> |
|---|---|
| date | Fri, 21 May 2004 12:55:20 +0000 |
| parents | 078d3f6136ea |
| children | 8214560941f4 |
comparison
equal
deleted
inserted
replaced
| 2352:0d302e93abd3 | 2353:bf3f75134e03 |
|---|---|
| 1 ================== | 1 ================== |
| 2 Developing Roundup | 2 Developing Roundup |
| 3 ================== | 3 ================== |
| 4 | 4 |
| 5 :Version: $Revision: 1.8 $ | 5 :Version: $Revision: 1.9 $ |
| 6 | 6 |
| 7 Note: the intended audience of this document is the developers of the core | 7 Note: the intended audience of this document is the developers of the core |
| 8 Roundup code. If you just wish to alter some behaviour of your Roundup | 8 Roundup code. If you just wish to alter some behaviour of your Roundup |
| 9 installation, see `customising roundup`_. | 9 installation, see `customising roundup`_. |
| 10 | 10 |
| 104 | 104 |
| 105 The administrators of the project reserve the right to boot developers who | 105 The administrators of the project reserve the right to boot developers who |
| 106 consistently check in code which is either broken or takes the codebase in | 106 consistently check in code which is either broken or takes the codebase in |
| 107 directions that have not been agreed to. | 107 directions that have not been agreed to. |
| 108 | 108 |
| 109 Internationalization Notes | |
| 110 -------------------------- | |
| 111 | |
| 112 How stuff works: | |
| 113 | |
| 114 1. Strings that may require translation (messages in human language) | |
| 115 are marked in the source code. This step is discussed in | |
| 116 `Marking Strings for Translation`_ section. | |
| 117 | |
| 118 2. These strings are all extracted into Message Template File | |
| 119 ``locale/roundup.pot`` (_`POT` file). See `Extracting Translatable | |
| 120 Messages`_ below. | |
| 121 | |
| 122 3. Language teams use POT file to make Message Files for national | |
| 123 languages (_`PO` files). All PO files for Roundup are kept in | |
| 124 the ``locale`` directory. Names of these files are target | |
| 125 locale names, usually just 2-letter language codes. `Translating | |
| 126 Messages`_ section of this chapter gives useful hints for | |
| 127 message translators. | |
| 128 | |
| 129 4. Translated Message Files are compiled into binary form (_`MO` files) | |
| 130 and stored in ``locale`` directory (but not kept in the `Roundup | |
| 131 CVS`_ repository, as they may be easily made from PO files). | |
| 132 See `Compiling Message Catalogs`_ section. | |
| 133 | |
| 134 5. Roundup installer creates runtime locale structure on the file | |
| 135 system, putting MO files in their appropriate places. | |
| 136 | |
| 137 6. Runtime internationalization (_`I18N`) services use these MO files | |
| 138 to translate program messages into language selected by current | |
| 139 Roundup user. Roundup command line interface uses locale name | |
| 140 set in OS environment variable ``LANGUAGE``, ``LC_ALL``, | |
| 141 ``LC_MESSAGES``, or ``LANG`` (in that order). Roundup Web User | |
| 142 Interface uses language selected by currently authenticated user. | |
| 143 | |
| 144 Additional details may be found in `GNU gettext`_ and Python `gettext | |
| 145 module`_ documentation. | |
| 146 | |
| 147 `Roundup source distribution`_ includes POT and PO files for message | |
| 148 translators, and also pre-built MO files to facilitate installations | |
| 149 from source. Roundup binary distribution includes MO files only. | |
| 150 | |
| 151 .. _GNU gettext: | |
| 152 | |
| 153 GNU gettext package | |
| 154 ^^^^^^^^^^^^^^^^^^^ | |
| 155 | |
| 156 This chapter is full of references to GNU `gettext package`_. | |
| 157 GNU gettext is a "must have" for nearly all steps of internationalizing | |
| 158 any program, and it's manual is definetely a recommended reading | |
| 159 for people involved in `I18N`_. | |
| 160 | |
| 161 There are GNU gettext ports to all major OS platforms. | |
| 162 Windows binaries are available from `GNU mirror sites`_. | |
| 163 | |
| 164 Roundup does not use GNU gettext at runtime, but it's tools | |
| 165 are used for `extracting translatable messages`_, `compiling | |
| 166 message catalogs`_ and, optionally, for `translating messages`_. | |
| 167 | |
| 168 Note that ``gettext`` package in some OS distributions means just | |
| 169 runtime tools and libraries. In such cases gettext development tools | |
| 170 are usually distributed in separate package named ``gettext-devel``. | |
| 171 | |
| 172 Marking Strings for Translation | |
| 173 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 174 | |
| 175 Strings that need translation must be marked in the source code. | |
| 176 Following subsections explain how this is done in different cases. | |
| 177 | |
| 178 If translatable string is used as a format string, it is recommended | |
| 179 to always use *named* format specifiers:: | |
| 180 | |
| 181 _('Index of %(classname)s') % locals() | |
| 182 | |
| 183 This helps translators to better understand the context of the | |
| 184 message and, in Python, remove format specifier altogether (which | |
| 185 is sometimes useful, especially in singular cases of `Plural Forms`_). | |
| 186 | |
| 187 When there is more than one format specifier in the translatable | |
| 188 format string, named format specifiers *must* be used almost always, | |
| 189 because translation may require different order of items. | |
| 190 | |
| 191 It is better to *not* mark for translation strings that are not | |
| 192 locale-dependent, as this makes it more difficult to keep track | |
| 193 of translation completeness. For example, string ``</ol></body></html>`` | |
| 194 (in ``index()`` method of the request handler in ``roundup_server`` | |
| 195 script) has no human readable parts at all, and needs no translations. | |
| 196 Such strings are left untranslated in PO files, and are reported | |
| 197 as such by PO status checkers (e.g. ``msgfmt --statistics``). | |
| 198 | |
| 199 Command Line Interfaces | |
| 200 ~~~~~~~~~~~~~~~~~~~~~~~ | |
| 201 | |
| 202 Scripts and routines run from the command line use "static" language | |
| 203 defined by environment variables recognized by ``gettext`` module | |
| 204 from Python library (``LANGUAGE``, ``LC_ALL``, ``LC_MESSAGES``, and | |
| 205 ``LANG``). Primarilly, these are ``roundup-admin`` script and | |
| 206 ``admin.py`` module, but also help texts and startup error messages | |
| 207 in other scripts and their supporting modules. | |
| 208 | |
| 209 For these interfaces, Python ``gettext`` engine must be initialized | |
| 210 to use Roundup message catalogs. This is normally done by including | |
| 211 the following line in the module imports:: | |
| 212 | |
| 213 from i18n import _, ngettext | |
| 214 | |
| 215 Simple translations are automatically marked by calls to builtin | |
| 216 message translation function ``_()``:: | |
| 217 | |
| 218 print _("This message is translated") | |
| 219 | |
| 220 Translations for messages whose grammatical depends on a number | |
| 221 must be done by ``ngettext()`` function:: | |
| 222 | |
| 223 print ngettext("Nuked %i file", "Nuked %i files", number_of_files_nuked) | |
| 224 | |
| 225 User Interfaces | |
| 226 ~~~~~~~~~~~~~~~ | |
| 227 | |
| 228 *(not yet)* | |
| 229 | |
| 230 This includes Mail Gateway and Web User Interfaces, where translation | |
| 231 depends on the language of current Roundup User. These translations | |
| 232 will be done by the tracker configuration object. Translatable strings | |
| 233 will be automatically marked by calls to the ``_()`` and ``ngettext()`` | |
| 234 methods of that object:: | |
| 235 | |
| 236 self.config._("This message is translated") | |
| 237 self.config.ngettext("Nuked %i file", "Nuked %i files", | |
| 238 number_of_files_nuked) | |
| 239 | |
| 240 Deferred Translations | |
| 241 ~~~~~~~~~~~~~~~~~~~~~ | |
| 242 | |
| 243 Sometimes translatable strings appear in the source code in untranslated | |
| 244 form [#note_admin.py]_ and must be translated elsewhere. | |
| 245 Example:: | |
| 246 | |
| 247 for meal in ("spam", "egg", "beacon"): | |
| 248 print _(meal) | |
| 249 | |
| 250 In such cases, strings must be marked for translation without actual | |
| 251 call to the translating function. To mark these strings, we use Python | |
| 252 feature of automatic concatenation of adjacent strings and different | |
| 253 types of string quotes:: | |
| 254 | |
| 255 strings_to_translate = ( | |
| 256 ''"This string will be translated", | |
| 257 ""'me too', | |
| 258 ''r"\raw string", | |
| 259 ''""" | |
| 260 multiline string""" | |
| 261 ) | |
| 262 | |
| 263 .. [#note_admin.py] In current Roundup sources, this feature is | |
| 264 extensively used in the ``admin`` module using method docstrings | |
| 265 as help messages. | |
| 266 | |
| 267 Extracting Translatable Messages | |
| 268 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 269 | |
| 270 The most common tool for message extraction is ``xgettext`` utility | |
| 271 from `GNU gettext package`_. Unfortunately, this utility has no means | |
| 272 of `Deferred Translations`_ in Python sources. There is ``xpot`` tool | |
| 273 from Francois Pinard free `PO utilities`_ that allows to mark strings | |
| 274 for deferred translations, but it does not handle `plural forms`_. | |
| 275 | |
| 276 Roundup overcomes these limitations by using both of these utilities. | |
| 277 This means that you need both `GNU gettext`_ tools and `PO utilities`_ | |
| 278 to build the Message Template File yourself. | |
| 279 | |
| 280 Latest Message Template File is kept in `Roundup CVS`_ and distributed | |
| 281 with `Roundup Source`_. If you wish to rebuild the template yourself, | |
| 282 make sure that you have both ``xpot`` and ``xgettext`` installed and | |
| 283 just run ``gmake`` (or ``make``, if you are on a `GNU`_ system like | |
| 284 `linux`_ or `cygwin`_) in the ``locale`` directory. | |
| 285 | |
| 286 Translating Messages | |
| 287 ^^^^^^^^^^^^^^^^^^^^ | |
| 288 | |
| 289 Gettext Message File (`PO`_ file) is a plain text file, that can be created | |
| 290 by simple copying ``roundup.pot`` to new .po file, like this:: | |
| 291 | |
| 292 $ cp roundup.pot ru.po | |
| 293 | |
| 294 The name of PO file is target locale name, usually just 2-letter language | |
| 295 code (``ru`` for Russian in the above example). Alternatively, PO file | |
| 296 may be initialized by ``msginit`` utility from `GNU gettext`_ tools:: | |
| 297 | |
| 298 $ msginit -i roundup.pot | |
| 299 | |
| 300 ``msginit`` will check your current locale, and initialize the header | |
| 301 entry, setting language name, rules for `plural forms`_ and, if available, | |
| 302 translator's name and email address. The name for PO file is also chosen | |
| 303 based on current locale. | |
| 304 | |
| 305 Next, you will need to edit this file, filling all ``msgstr`` lines with | |
| 306 translations of the above ``msgid`` entries. PO file is a plain text | |
| 307 file that can be edited with any text editor. However, there are several | |
| 308 tools that may help you with this process: | |
| 309 | |
| 310 - ``po-mode`` for `emacs`_. One of `GNU gettext`_ tools. Very handy, | |
| 311 definitely recommended if you are comfortable with emacs. Cannot | |
| 312 handle `plural forms`_ per se, but allows to edit them in simple | |
| 313 text mode. | |
| 314 | |
| 315 - `po filetype plugin`_ for `vim`_. Does not do as much as ``po-mode``, | |
| 316 but helps in finding untranslated and fuzzy strings, and checking | |
| 317 code references. Please contact `alexander smishlajev`_ if you | |
| 318 prefer this, as i have patched this plugin a bit. I have also | |
| 319 informed the original plugin author about these changes, but got | |
| 320 no reply so far. | |
| 321 | |
| 322 - `poEdit`_ by Vaclav Slavik. Nice cross-platform GUI editor. | |
| 323 Unfortunately, it does not handle `plural forms`_. Even worse, | |
| 324 it deletes all messages with plural forms when the file is saved. | |
| 325 Still, it may be useful to initially translate most of the messages | |
| 326 and add plural form messages later. | |
| 327 | |
| 328 - `KBabel`_. Being part of `KDE`_, it works in X windows only. | |
| 329 At the first glance looks pretty hairy, with all bells and whistles. | |
| 330 Haven't had much experience with it, though. | |
| 331 | |
| 332 Compiling Message Catalogs | |
| 333 ^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 334 | |
| 335 Message catalogs (`PO`_ files) must be compiled into binary form | |
| 336 (`MO`_ files) before they can be used in the application. This | |
| 337 compilation is handled by ``msgfmt`` utility from `GNU gettext`_ | |
| 338 tools. ``GNUmakefile`` in the ``locale`` directory automatically | |
| 339 compiles all existing message catalogs after updating them from | |
| 340 Roundup source files. If you wish to rebuild an individual `MO`_ | |
| 341 file without making everything else, you may, for example:: | |
| 342 | |
| 343 $ msgfmt --statistics -o ru.mo ru.po | |
| 344 | |
| 345 This way, message translators can check their `PO`_ files without | |
| 346 extracting strings from source. (Note: String extraction requires | |
| 347 additional utility that is not part of `GNU gettext`_. See `Extracting | |
| 348 Translatable Messages`_.) | |
| 109 | 349 |
| 110 ----------------- | 350 ----------------- |
| 111 | 351 |
| 112 Back to `Table of Contents`_ | 352 Back to `Table of Contents`_ |
| 113 | 353 |
| 114 .. _`Table of Contents`: index.html | 354 .. _`Table of Contents`: index.html |
| 115 .. _`Customising Roundup`: customizing.html | 355 .. _`Customising Roundup`: customizing.html |
| 116 .. _`Roundup's Design Document`: spec.html | 356 .. _`Roundup's Design Document`: spec.html |
| 117 .. _`implementation notes`: implementation.html | 357 .. _`implementation notes`: implementation.html |
| 358 | |
| 359 | |
| 360 .. _External hyperlink targets: | |
| 361 | |
| 362 .. _alexander smishlajev: | |
| 363 .. _als: http://sourceforge.net/users/a1s/ | |
| 364 .. _cygwin: http://www.cygwin.com/ | |
| 365 .. _emacs: http://www.gnu.org/software/emacs/ | |
| 366 .. _gettext package: http://www.gnu.org/software/gettext/ | |
| 367 .. _gettext module: http://docs.python.org/lib/module-gettext.html | |
| 368 .. _GNU: http://www.gnu.org/ | |
| 369 .. _GNU mirror sites: http://www.gnu.org/prep/ftp.html | |
| 370 .. _KBabel: http://i18n.kde.org/tools/kbabel/ | |
| 371 .. _KDE: http://www.kde.org/ | |
| 372 .. _linux: http://www.linux.org/ | |
| 373 .. _Plural Forms: | |
| 374 http://www.gnu.org/software/gettext/manual/html_node/gettext_150.html | |
| 375 .. _po filetype plugin: | |
| 376 http://vim.sourceforge.net/scripts/script.php?script_id=695 | |
| 377 .. _PO utilities: http://po-utils.progiciels-bpi.ca/ | |
| 378 .. _poEdit: http://poedit.sourceforge.net/ | |
| 379 .. _Roundup CVS: http://sourceforge.net/cvs/?group_id=31577 | |
| 380 .. _Roundup Source: | |
| 381 .. _Roundup source distribution: | |
| 382 .. _Roundup binary distribution: | |
| 383 http://sourceforge.net/project/showfiles.php?group_id=31577 | |
| 384 .. _vim: http://www.vim.org/ |
