Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Changes between Version 16 and Version 17 of Internationalization


Ignore:
Timestamp:
04/29/06 21:17:06 (13 years ago)
Author:
roger.demetrescu
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Internationalization

    v16 v17  
    1 = To internationalize your application, you have to make sure of the following steps: = 
    2  
    3  1. That you mark your text strings using the _() function. 
    4  1. That you have create message catalogs in the right directory structure for all your text strings and supported languages. 
    5  1. That any date or number strings are formatted using the turbogears.i18n formatting functions. 
    6  
    7 == 1. Mark your text strings with _() == 
    8  
    9 All text strings you want translated should be included in the _() function. This function is builtin to turbogears, so you don't need to import it specifically into your module, if you have already called "import turbogears". 
    10  
    11 For example: 
    12  
    131{{{ 
    14 #!python 
    15 import turbogears 
    16  
    17 from turbogears import controllers 
    18  
    19 class Controller(controllers.Root): 
    20  
    21     @turbogears.expose(html="myapp.templates.welcome") 
    22  
    23     def index(self): 
    24         return dict(message=_("Welcome")) 
     2#!html 
     3<br> 
     4<div style="display:block; padding: 4px; border: 2px solid red; color: #C00; font-weight:bold;"> 
     5Note: this entry was moved to TurboGears newsdoc (docs/i18n/index.html) 
     6</div> 
     7<br> 
    258}}} 
    26  
    27 If you want to explicitly pass in the locale in the _() call, you can do this: 
    28  
    29 {{{ 
    30 #!python 
    31 print _("Welcome", "de") 
    32 }}} 
    33  
    34 Handling text strings in Kid templates is somewhat easier. If you set the cherrypy configuration setting '''i18n.runTemplateFilter''' to True, all text inside your Kid templates will be passed through _() automatically. The user locale (see below) can be overriden in your template by using the "lang" attribute, for example: 
    35  
    36 {{{ 
    37 #!text/html 
    38 <div> 
    39   <p>Welcome</p> 
    40   <p lang="de">Welcome</p> 
    41 </div> 
    42 }}} 
    43  
    44 The first "Welcome" will be translated using the user locale setting, the second using the German locale. Assuming your user locale is English, you would see: 
    45  
    46 {{{ 
    47 #!text/html 
    48 <div> 
    49   <p>Welcome</p> 
    50   <p lang="de">Willkommen</p> 
    51 </div> 
    52 }}} 
    53  
    54 However, attribute values are not translated and so have to be handled explicitly by using the _() call: 
    55  
    56 {{{ 
    57 #!text/html 
    58 <img py:attrs="src=_('flag_icon_gb.bmp')" /> 
    59 }}} 
    60  
    61 Note that text inside widget templates, etc. will also be translated. 
    62  
    63 == 2. Create your message catalogs == 
    64  
    65 Use the Python scripts in tools/i18n, pygettext.py and msgfmt.py, to create your .po file and .mo files. For details on using this tool and creating your message catalogs, see [http://docs.python.org/lib/module-gettext.html gettext]. Basically you should have a directory structure like this: 
    66  
    67 {{{ 
    68 myapp/ 
    69     locales/ 
    70         messages.pot 
    71         en/ 
    72             LC_MESSAGES/ 
    73                 messages.po 
    74  
    75                 messages.mo 
    76         de/ 
    77             LC_MESSAGES/ 
    78                 messages.po 
    79  
    80                 messages.mo 
    81 }}} 
    82  
    83 Eventually we should have tools in tg-admin to handle text extraction and compilation. ''There is a patch (#126) that would provide this kind of functionality, hopefully to be included in 0.9 release''. 
    84  
    85 By default, _() looks for subdirectory "locales" and domain "messages" in your project directory. You can override these settings in your config file by setting '''i18n.localeDir''' and '''i18n.domain''' respectively. 
    86  
    87 If a language file(.mo) is not found, the _() call will return the plain text string. 
    88  
    89 == 3. Localize your dates and numbers == 
    90  
    91 The i18n package has a number of useful functions for handling date, location and number formats. Data for these formats is contained in Python modules under turbogears/i18n/data, for example the module for Danish is turbogears/i18n/data/da.py. The functions include: 
    92  
    93 {{{ 
    94 #!python 
    95 format_date: returns a localized date string 
    96  
    97 get_countries: returns a list of tuples, with the international country code and localized name (e.g. ("AU", "Australia")) 
    98  
    99 format_currency: returns a formatted currency value (e.g. in German 56.89 > 56,89) 
    100 }}} 
    101  
    102 === Finding the user locale === 
    103  
    104 The default locale function, _get_locale, can be overriden by your own locale using the config setting "i18n.getLocale". This default function finds the locale setting in the following order: 
    105  
    106  1. By looking for a session value. By default this is "locale", but can be changed in the config setting "i18n.sessionKey". 
    107  1. By looking in the HTTP Accept-Language header for the most preferred language. 
    108  1. By using the default locale (config setting "i18n.defaultLocale", by default "en"). 
    109  
    110 === Encoding === 
    111  
    112 The _() and all formatting functions return unicode strings. 
    113  
    114 = Receiving international (UTF-8) form data = 
    115  
    116 The first thing to do is to add a tag similar to the following at the head of your template: 
    117  
    118 {{{<meta content="text/html; charset=UTF-8" http-equiv="content-type" />}}} 
    119  
    120 It will let the browser know it operates in "unicode mode". 
    121  
    122 When the browser sends unicode data in a request (via a textarea, for example), CherryPy gives you the string as is. 
    123 you need to convert it to unicode yourself: 
    124 {{{ 
    125 #!python 
    126 @turbogears.expose(template="myproject.templates.welcome") 
    127 def test(self, text): 
    128     text = text.encode("utf-8") 
    129     # ... The rest of the code 
    130 }}} 
    131  
    132 Another, easier way, is to use a CherryPy filter. A filter is a function that runs on the input/output automatically. CherryPy has several built-ins. One of them is {{{decoding_filter}}}, that decodes all of the incoming request parameters using a given encoding. 
    133  
    134 In your project's config.py, add this: 
    135 {{{ 
    136 #!python 
    137 path("/") 
    138 decoding_filter.on =  True 
    139 decoding_filter.encoding = "utf-8" 
    140 }}} 
    141  
    142 To get Kid to work, you probably also want to setup a sane default encoding for your site. Add the following lines to /usr/lib/python2.4/site-packages/sizecustomize.py: 
    143 {{{ 
    144 #!python 
    145 import sys 
    146 reload(sys) 
    147 sys.setdefaultencoding("utf8") 
    148 }}} 
    149  
    150 You can ofcourse replace "utf8" with whichever coding you want.