Edgewall Software

Changes between Version 10 and Version 11 of CookBook/PluginL10N


Ignore:
Timestamp:
May 9, 2010, 7:03:56 PM (14 years ago)
Author:
Christian Boos
Comment:

reworked #Prepareplugincode (post-r9659)

Legend:

Unmodified
Added
Removed
Modified
  • CookBook/PluginL10N

    v10 v11  
    3131
    3232== Required workflow ==
    33 a walk-through
     33A walk-through...
    3434
    3535=== Prepare plugin code ===
    3636==== Import i18n/l10n helper programs ====
    37 For a '''fictional plugin 'foo' ''' just add
     37Pick a reasonably unique name for the catalog, e.g. ** 'foo' **
     38
     39This will be the basename for the various translation catalog files
     40(e.g. `<path>/locale/fr/LC_MESSAGES/foo.po` for the French catalog).
     41
     42At run-time, the translation functions (typically `_(...)`) have to know in which catalog the translation will be found. Specifying the 'foo' domain in every such call would be tedious, that's why there's a facility for creating partially instantiated domain-aware translation functions, `domain_functions`.
     43
     44This helper function should be called at module load time, like this:
    3845{{{#!python
    3946from trac.util.translation import domain_functions
    4047
    41 _, tag_, N_, add_domain = domain_functions('foo',
    42     '_', 'tag_', 'N_', 'add_domain')
    43 }}}
    44 at the beginning of the main python script file.
    45   // TODO  I think I'll change that to: //
    46 {{{#!python
    47 from trac.util.translation import domain_functions
    48 
    49 _, tag_, N_, add_domain = domain_functions('foo', ('_', 'tag_', 'N_', 'add_domain'))
    50 }}}
    51  //FIXME give the list of available domain functions//
    52 
    53 To bring in the compiled message catalog for actually using plugin's message catalogs you'll have to extend the `__init__` function of plugins main class as well. This could be done like this:
     48_, tag_, N_, add_domain = \
     49    domain_functions('foo', ('_', 'tag_', 'N_', 'add_domain'))
     50}}}
     51
     52The translation functions which can be bound to a domain are:
     53 - `'_'`: extract and translate
     54 - `'ngettext'`: extract and translate (singular, plural, num)
     55 - `'tgettext'`, `'tag_'`: same as `'_'` but for Markup
     56 - `'tngettext'`, `'tagn_'`: same as `'ngettext'` but for Markup
     57 - `'gettext'`: translate only, don't extract
     58 - `'N_'`: extract only, don't translate
     59 - `'add_domain'`: register the catalog file for the bound domain
     60
     61To inform Trac about where the plugin's message catalogs can be found, you'll have to call the `'add_domain'` obtained via `domain_functions`. One place to do this is in the `__init__` function of your plugin's main component, like this:
    5462{{{#!python
    5563    def __init__(self):
     64        import pkg_resources # here or with the other imports
    5665        # bind the 'foo' catalog to the specified locale directory
    5766        locale_dir = pkg_resources.resource_filename(__name__, 'locale')
    5867        add_domain(self.env.path, locale_dir)
    5968}}}
    60 assuming that folder `locale` will reside in `./foo/locale/` within the directory structure (as observable inside the Python egg after packaging).
    61 
    62 If you didn't have it in the source by now, add another import statement
    63 {{{#!python
    64 import pkg_resources
    65 }}}
    66 at the beginning of the plugin script as well or the line `locale_dir = ...` (see previous code snippet) will throw an '!ImportError'.
    67 
    68 The i18n/l10n helper programs are available inside the plugin now, but if the plugin code contains several python script files and you encounter text for translation in one of them too, you need to import the functions from the main script, say it's name is `api.py`, there:
     69assuming that folder `locale` will reside in the same folder as the file containing the code above, referred to as `<path>` (as observable inside the Python egg after packaging).
     70
     71The i18n/l10n helper programs are available inside the plugin now, but if the plugin code contains several python script files and you encounter text for translation in one of them too, you need to import the functions from the main script, say its name is `api.py`, there:
    6972{{{#!python
    7073from api import _, tag_, N_
    7174}}}
    72 {{{#!comment
    73 resume review here...
    74 }}}
     75
    7576
    7677==== Preset configuration for i18n/l10n helper programs ====
     
    8081add_comments = TRANSLATOR:
    8182msgid_bugs_address =
    82 output_file = foo/locale/messages.pot
    83 keywords = _ ngettext:1,2 N_ tag_
     83output_file = <path>/locale/messages.pot
     84# Note: specify as 'keywords' the functions for which the messages
     85#       should be extracted. This should match the list of functions
     86#       that you've listed in the `domain_functions()` call above.
     87keywords = _ N_ tag_
     88# Other example:
     89#keywords = _ ngettext:1,2 N_ tag_
    8490width = 72
    8591
    8692[init_catalog]
    87 input_file = foo/locale/messages.pot
    88 output_dir = foo/locale
     93input_file = <path>/locale/messages.pot
     94output_dir = <path>/locale
    8995domain = foo
    9096
    9197[compile_catalog]
    92 directory = foo/locale
     98directory = <path>/locale
    9399domain = foo
    94100
    95101[update_catalog]
    96 input_file = foo/locale/messages.pot
    97 output_dir = foo/locale
     102input_file = <path>/locale/messages.pot
     103output_dir = <path>/locale
    98104domain = foo
    99105}}}
    100 This will tell the i18n/l10n helper programs where to look for and store message catalog files. Since we prepare for a domain dedicted to the plugin you need to change the configuration to the existing plugin directory (that is a short all-lowercase form of plugin's name in most cases) wherever it reads `foo` in the example.
    101 
    102 In the `extract_messages` section there are other lines you may like to change. Starting with `add_comments` there is the place to announce yourself as the translator by adding your name after the default `TRANSLATOR:` label. To allow for direct feedback regarding your translation add a valid e-mail address or a mailing list dedicated to translation issues to `msgid_bugs_address`.
     106Replace `<path>` as appropriate (i.e. the relative path to the folder containing the `locale` directory, for example `mytracplugin`).
     107
     108This will tell the i18n/l10n helper programs where to look for and store message catalog files.
     109
     110In the `extract_messages` section there are other lines you may like to change.
     111
     112// Starting with `add_comments` there is the place to announce yourself as the translator by adding your name after the default `TRANSLATOR:` label. To allow for direct feedback regarding your translation add a valid e-mail address or a mailing list dedicated to translation issues to `msgid_bugs_address`. //
     113 Well, no, add_comments simply list the tags in the comments surrounding the calls to the translation functions in the source code that have to be propagated to the catalogs... (see Babel:wiki:Documentation/0.9/setup.html#extract-messages)
     114
     115{{{#!comment
     116resume review here...
     117}}}
    103118
    104119==== Mark text for extraction ====