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/

Roundup Issue Tracker: http://roundup-tracker.org/