Premiere version : mise en route du suivi.
[auf_roundup.git] / doc / .svn / text-base / developers.txt.svn-base
1 ==================
2 Developing Roundup
3 ==================
4
5 .. note::
6    The intended audience of this document is the developers of the core
7    Roundup code. If you just wish to alter some behaviour of your Roundup
8    installation, see `customising roundup`_.
9
10 .. contents::
11
12 Getting Started
13 ---------------
14
15 Anyone wishing to help in the development of Roundup must read `Roundup's
16 Design Document`_ and the `implementation notes`_.
17
18 All development is coordinated through two resources:
19
20 - roundup-dev mailing list at
21   http://lists.sourceforge.net/mailman/listinfo/roundup-devel
22 - The issue tracker running at
23   http://issues.roundup-tracker.org/
24
25 Website, wiki
26 -------------
27
28 1. ssh -t <username>,roundup@shell.sourceforge.net create
29 2. cd /home/groups/r/ro/roundup
30 3. follow instructions in README.txt
31
32
33 Issue Tracker
34 -------------
35
36 The tracker resides on psf.upfronthosting.co.za. The roundup installation
37 belongs to the user roundup. In ~roundup, all trackers are stored and
38 the roundup code itself. roundup is started through /etc/init.d/roundup;
39 other parts of the installation are started through
40 /etc/init.d/{postgresql-8-1,spambayes,postfix}.
41
42 The machine is operated by Upfronthosting in South Africa. The meta
43 tracker is http://psf.upfronthosting.co.za/roundup/meta/
44 In this tracker, Upfronthosting people are the users izak and roche.
45
46 The Roundup tracker http://issues.roundup-tracker.org/ is in
47 ~roundup/trackers/roundup
48
49 The configuration is in the "web/trunk/issues" section of Roundup's
50 Subversion repository and copied manually to the live tracker.
51
52 A checkout of the roundup sources is in ~roundup/src/roundup-src.
53
54
55 Small Changes
56 -------------
57
58 Most small changes can be submitted through the issue tracker, with
59 patches attached that give context diffs of the affected source.
60
61
62 SVN Access
63 ----------
64
65 See http://www.roundup-tracker.org/code.html.
66 For all other questions ask on the development mailinglist.
67
68
69 Project Rules
70 -------------
71
72 Mostly the project follows Guido's Style (though naming tends to be a little
73 relaxed sometimes). In short:
74
75 - 80 column width code
76 - 4-space indentations
77 - All modules must have an Id line near the top
78
79 Other project rules:
80
81 - New functionality must be documented, even briefly (so at least we know
82   where there's missing documentation) and changes to tracker configuration
83   must be logged in the upgrading document.
84 - subscribe to roundup-checkins to receive checkin notifications from the
85   other developers with write access to the source-code repository.
86 - discuss any changes with the other developers on roundup-dev. If nothing
87   else, this makes sure there's no rude shocks
88 - write unit tests for changes you make (where possible), and ensure that
89   all unit tests run before committing changes
90 - run pychecker over changed code
91
92 The administrators of the project reserve the right to boot developers who
93 consistently check in code which is either broken or takes the codebase in
94 directions that have not been agreed to.
95
96
97 Debugging Aids
98 --------------
99
100 See `debugging.txt`_.
101
102 Internationalization Notes
103 --------------------------
104
105 How stuff works:
106
107 1. Strings that may require translation (messages in human language)
108    are marked in the source code.  This step is discussed in
109    `Marking Strings for Translation`_ section.
110
111 2. These strings are all extracted into Message Template File
112    ``locale/roundup.pot`` (_`POT` file).  See `Extracting Translatable
113    Messages`_ below.
114
115 3. Language teams use POT file to make Message Files for national
116    languages (_`PO` files).  All PO files for Roundup are kept in
117    the ``locale`` directory.  Names of these files are target
118    locale names, usually just 2-letter language codes.  `Translating
119    Messages`_ section of this chapter gives useful hints for
120    message translators.
121
122 4. Translated Message Files are compiled into binary form (_`MO` files)
123    and stored in ``locale`` directory (but not kept in the source code
124    repository, as they may be easily made from PO files).
125    See `Compiling Message Catalogs`_ section.
126
127 5. Roundup installer creates runtime locale structure on the file
128    system, putting MO files in their appropriate places.
129
130 6. Runtime internationalization (_`I18N`) services use these MO files
131    to translate program messages into language selected by current
132    Roundup user.  Roundup command line interface uses locale name
133    set in OS environment variable ``LANGUAGE``, ``LC_ALL``,
134    ``LC_MESSAGES``, or ``LANG`` (in that order).  Roundup Web User
135    Interface uses language selected by currently authenticated user.
136
137 Additional details may be found in `GNU gettext`_ and Python `gettext
138 module`_ documentation.
139
140 `Roundup source distribution`_ includes POT and PO files for message
141 translators, and also pre-built MO files to facilitate installations
142 from source.  Roundup binary distribution includes MO files only.
143
144 .. _GNU gettext:
145
146 GNU gettext package
147 ^^^^^^^^^^^^^^^^^^^
148
149 This chapter is full of references to GNU `gettext package`_.
150 GNU gettext is a "must have" for nearly all steps of internationalizing
151 any program, and it's manual is definetely a recommended reading
152 for people involved in `I18N`_.
153
154 There are GNU gettext ports to all major OS platforms.
155 Windows binaries are available from `GNU mirror sites`_.
156
157 Roundup does not use GNU gettext at runtime, but it's tools
158 are used for `extracting translatable messages`_, `compiling
159 message catalogs`_ and, optionally, for `translating messages`_.
160
161 Note that ``gettext`` package in some OS distributions means just
162 runtime tools and libraries.  In such cases gettext development tools
163 are usually distributed in separate package named ``gettext-devel``.
164
165 Marking Strings for Translation
166 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
167
168 Strings that need translation must be marked in the source code.
169 Following subsections explain how this is done in different cases.
170
171 If translatable string is used as a format string, it is recommended
172 to always use *named* format specifiers::
173
174   _('Index of %(classname)s') % locals()
175
176 This helps translators to better understand the context of the
177 message and, with Python formatting, remove format specifier altogether
178 (which is sometimes useful, especially in singular cases of `Plural Forms`_).
179
180 When there is more than one format specifier in the translatable
181 format string, named format specifiers **must** be used almost always,
182 because translation may require different order of items.
183
184 It is better to *not* mark for translation strings that are not
185 locale-dependent, as this makes it more difficult to keep track
186 of translation completeness.  For example, string ``</ol></body></html>``
187 (in ``index()`` method of the request handler in ``roundup_server``
188 script) has no human readable parts at all, and needs no translations.
189 Such strings are left untranslated in PO files, and are reported
190 as such by PO status checkers (e.g. ``msgfmt --statistics``).
191
192 Command Line Interfaces
193 ~~~~~~~~~~~~~~~~~~~~~~~
194
195 Scripts and routines run from the command line use "static" language
196 defined by environment variables recognized by ``gettext`` module
197 from Python library (``LANGUAGE``, ``LC_ALL``, ``LC_MESSAGES``, and
198 ``LANG``).  Primarilly, these are ``roundup-admin`` script and
199 ``admin.py`` module, but also help texts and startup error messages
200 in other scripts and their supporting modules.
201
202 For these interfaces, Python ``gettext`` engine must be initialized
203 to use Roundup message catalogs.  This is normally done by including
204 the following line in the module imports::
205
206   from i18n import _, ngettext
207
208 Simple translations are automatically marked by calls to builtin
209 message translation function ``_()``::
210
211   print _("This message is translated")
212
213 Translations for messages whose grammatical depends on a number
214 must be done by ``ngettext()`` function::
215
216   print ngettext("Nuked %i file", "Nuked %i files", number_of_files_nuked)
217
218 Deferred Translations
219 ~~~~~~~~~~~~~~~~~~~~~
220
221 Sometimes translatable strings appear in the source code in untranslated
222 form [#note_admin.py]_ and must be translated elsewhere.
223 Example::
224
225   for meal in ("spam", "egg", "beacon"):
226       print _(meal)
227
228 In such cases, strings must be marked for translation without actual
229 call to the translating function.  To mark these strings, we use Python
230 feature of automatic concatenation of adjacent strings and different
231 types of string quotes::
232
233   strings_to_translate = (
234       ''"This string will be translated",
235       ""'me too',
236       ''r"\raw string",
237       ''"""
238       multiline string"""
239   )
240
241 .. [#note_admin.py] In current Roundup sources, this feature is
242    extensively used in the ``admin`` module using method docstrings
243    as help messages.
244
245 Web User Interface
246 ~~~~~~~~~~~~~~~~~~
247
248 For Web User Interface, translation services are provided by Client
249 object.  Action classes have methods ``_()`` and ``gettext()``,
250 delegating translation to the Client instance.  In HTML templates,
251 translator object is available as context variable ``i18n``.
252
253 HTML templates have special markup for translatable strings.
254 The syntax for this markup is defined on `ZPTInternationalizationSupport`_
255 page.  Roundup translation service currently ignores values for
256 ``i18n:domain``, ``i18n:source`` and ``i18n:target``.
257
258 Template markup examples:
259
260 * simplest case::
261
262     <div i18n:translate="">
263      Say
264      no
265      more!
266     </div>
267
268   this will result in msgid ``"Say no more!"``, with all leading and
269   trailing whitespace stripped, and inner blanks replaced with single
270   space character.
271
272 * using variable slots::
273
274     <div i18n:translate="">
275      And now...<br/>
276      No.<span tal:replace="number" i18n:name="slideNo" /><br/>
277      THE LARCH
278     </div>
279
280   Msgid will be: ``"And now...<br /> No.${slideNo}<br /> THE LARCH"``.
281   Template rendering will use context variable ``number`` (you may use
282   any expression) to put instead of ``${slideNo}`` in translation.
283
284 * attribute translation::
285
286     <button name="btn_wink" value=" Wink " i18n:attributes="value" />
287
288   will translate the caption (and return value) for the "wink" button.
289
290 * explicit msgids.  Sometimes it may be useful to specify msgid
291   for the element translation explicitely, like this::
292
293     <span i18n:translate="know what i mean?">this text is ignored</span>
294
295   When rendered, element contents will be replaced by translation
296   of the string specified in ``i18n:translate`` attribute.
297
298 * ``i18n`` in `TALES`_.  You may translate strings in `TALES`_ python
299   expressions::
300
301     <span tal:replace="python: i18n.gettext('Oh, wicked.')" />
302
303 * plural forms.  There is no markup for plural forms in `TAL`_ i18n.
304   You must use python expression for that::
305
306     <span tal:replace="python: i18n.ngettext(
307       'Oh but it\'s only %i shilling.',
308       'Oh but it\'s only %i shillings.',
309       fine) % fine"
310     />
311
312 Extracting Translatable Messages
313 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
314
315 The most common tool for message extraction is ``xgettext`` utility
316 from `GNU gettext package`_.  Unfortunately, this utility has no means
317 of `Deferred Translations`_ in Python sources.  There is ``xpot`` tool
318 from Francois Pinard free `PO utilities`_ that allows to mark strings
319 for deferred translations, but it does not handle `plural forms`_.
320
321 Roundup overcomes these limitations by using both of these utilities.
322 This means that you need both `GNU gettext`_ tools and `PO utilities`_
323 to build the Message Template File yourself.
324
325 Latest Message Template File is kept in the source code repository 
326 and distributed with `Roundup Source`_.  
327 If you wish to rebuild the template yourself,
328 make sure that you have both ``xpot`` and ``xgettext`` installed and
329 just run ``gmake`` (or ``make``, if you are on a `GNU`_ system like
330 `linux`_ or `cygwin`_) in the ``locale`` directory.
331
332 For on-site i18n, Roundup provides command-line utility::
333
334   roundup-gettext <tracker_home>
335
336 extracting translatable messages from tracker's html templates.
337 This utility creates message template file ``messages.pot`` in
338 ``locale`` subdirectory of the tracker home directory.  Translated
339 messages may be put in *locale*.po files (where *locale* is selected
340 locale name) in the same directory, e.g.: ``locale/ru.po``.
341 These message catalogs are searched prior to system-wide translations
342 kept in the ``share`` directory.
343
344 Translating Messages
345 ^^^^^^^^^^^^^^^^^^^^
346
347 Gettext Message File (`PO`_ file) is a plain text file, that can be created
348 by simple copying ``roundup.pot`` to new .po file, like this::
349
350   $ cp roundup.pot ru.po
351
352 The name of PO file is target locale name, usually just 2-letter language
353 code (``ru`` for Russian in the above example).  Alternatively, PO file
354 may be initialized by ``msginit`` utility from `GNU gettext`_ tools::
355
356   $ msginit -i roundup.pot
357
358 ``msginit`` will check your current locale, and initialize the header
359 entry, setting language name, rules for `plural forms`_ and, if available,
360 translator's name and email address.  The name for PO file is also chosen
361 based on current locale.
362
363 Next, you will need to edit this file, filling all ``msgstr`` lines with
364 translations of the above ``msgid`` entries.  PO file is a plain text
365 file that can be edited with any text editor.  However, there are several
366 tools that may help you with this process:
367
368  - `poEdit`_ by Vaclav Slavik.  Very nice cross-platform GUI editor.
369
370  - `KBabel`_.  Being part of `KDE`_, it works in X windows only.
371     At the first glance looks pretty hairy, with all bells and whistles.
372     Haven't had much experience with it, though.
373
374  - ``po-mode`` for `emacs`_.  One of `GNU gettext`_ tools.  Very handy,
375    definitely recommended if you are comfortable with emacs.  Cannot
376    handle `plural forms`_ per se, but allows to edit them in simple
377    text mode.
378
379  - `po filetype plugin`_ for `vim`_.  Does not do as much as ``po-mode``,
380    but helps in finding untranslated and fuzzy strings, and checking
381    code references.  Please contact `alexander smishlajev`_ if you
382    prefer this, as i have patched this plugin a bit.  I have also
383    informed the original plugin author about these changes, but got
384    no reply so far.
385
386 Compiling Message Catalogs
387 ^^^^^^^^^^^^^^^^^^^^^^^^^^
388
389 Message catalogs (`PO`_ files) must be compiled into binary form
390 (`MO`_ files) before they can be used in the application.  This
391 compilation is handled by ``msgfmt`` utility from `GNU gettext`_
392 tools.  ``GNUmakefile`` in the ``locale`` directory automatically
393 compiles all existing message catalogs after updating them from
394 Roundup source files.  If you wish to rebuild an individual `MO`_
395 file without making everything else, you may, for example::
396
397   $ msgfmt --statistics -o ru.mo ru.po
398
399 This way, message translators can check their `PO`_ files without
400 extracting strings from source.  (Note: String extraction requires
401 additional utility that is not part of `GNU gettext`_.  See `Extracting
402 Translatable Messages`_.)
403
404 At run time, Roundup automatically compiles message catalogs whenever
405 `PO`_ file is changed.
406
407 .. _`Customising Roundup`: customizing.html
408 .. _`Roundup's Design Document`: spec.html
409 .. _`implementation notes`: implementation.html
410
411
412 .. _External hyperlink targets:
413
414 .. _alexander smishlajev:
415 .. _als: http://sourceforge.net/users/a1s/
416 .. _cygwin: http://www.cygwin.com/
417 .. _emacs: http://www.gnu.org/software/emacs/
418 .. _gettext package: http://www.gnu.org/software/gettext/
419 .. _gettext module: http://docs.python.org/lib/module-gettext.html
420 .. _GNU: http://www.gnu.org/
421 .. _GNU mirror sites: http://www.gnu.org/prep/ftp.html
422 .. _KBabel: http://i18n.kde.org/tools/kbabel/
423 .. _KDE: http://www.kde.org/
424 .. _linux: http://www.linux.org/
425 .. _Plural Forms:
426     http://www.gnu.org/software/gettext/manual/html_node/gettext_150.html
427 .. _po filetype plugin:
428     http://vim.sourceforge.net/scripts/script.php?script_id=695
429 .. _PO utilities: http://po-utils.progiciels-bpi.ca/
430 .. _poEdit: http://poedit.sourceforge.net/
431 .. _Roundup Source:
432 .. _Roundup source distribution:
433 .. _Roundup binary distribution:
434     http://sourceforge.net/project/showfiles.php?group_id=31577
435 .. _TAL:
436 .. _Template Attribute Language:
437    http://dev.zope.org/Wikis/DevSite/Projects/ZPT/TAL%20Specification%201.4
438 .. _TALES:
439 .. _Template Attribute Language Expression Syntax:
440    http://dev.zope.org/Wikis/DevSite/Projects/ZPT/TALES%20Specification%201.3
441 .. _vim: http://www.vim.org/
442 .. _ZPTInternationalizationSupport: http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/ZPTInternationalizationSupport
443