48 The goal of the *built-in* function `_` is only **to mark the |
48 The goal of the *built-in* function `_` is only **to mark the |
49 translatable strings**, it will only return the string to translate |
49 translatable strings**, it will only return the string to translate |
50 itself, but not its translation (it's actually another name for the |
50 itself, but not its translation (it's actually another name for the |
51 `unicode` builtin). |
51 `unicode` builtin). |
52 |
52 |
53 In the other hand the request's method `self._cw._` is meant to retrieve the |
53 In the other hand the request's method `self._cw._` is also meant to |
54 proper translation of translation strings in the requested language. |
54 retrieve the proper translation of translation strings in the |
|
55 requested language. |
55 |
56 |
56 Finally you can also use the `__` attribute of request object to get a |
57 Finally you can also use the `__` attribute of request object to get a |
57 translation for a string *which should not itself added to the catalog*, |
58 translation for a string *which should not itself added to the catalog*, |
58 usually in case where the actual msgid is created by string interpolation :: |
59 usually in case where the actual msgid is created by string interpolation :: |
59 |
60 |
60 self._cw.__('This %s' % etype) |
61 self._cw.__('This %s' % etype) |
61 |
62 |
62 In this example ._cw.__` is used instead of ._cw._` so we don't have 'This %s' in |
63 In this example ._cw.__` is used instead of ._cw._` so we don't have 'This %s' in |
63 messages catalogs. |
64 messages catalogs. |
64 |
65 |
65 |
|
66 Translations in cubicweb-tal template can also be done with TAL tags |
66 Translations in cubicweb-tal template can also be done with TAL tags |
67 `i18n:content` and `i18n:replace`. |
67 `i18n:content` and `i18n:replace`. |
68 |
68 |
69 |
|
70 If you need to add messages on top of those that can be found in the source, |
69 If you need to add messages on top of those that can be found in the source, |
71 you can create a file named `i18n/static-messages.pot`. |
70 you can create a file named `i18n/static-messages.pot`. |
|
71 |
|
72 You could put there messages not found in the python sources or |
|
73 overrides for some messages of used cubes. |
72 |
74 |
73 Generated string |
75 Generated string |
74 ```````````````` |
76 ```````````````` |
75 |
77 |
76 We do not need to mark the translation strings of entities/relations used by a |
78 We do not need to mark the translation strings of entities/relations used by a |
78 various actions are also generated. |
80 various actions are also generated. |
79 |
81 |
80 For exemple the following schema :: |
82 For exemple the following schema :: |
81 |
83 |
82 Class EntityA(EntityType): |
84 Class EntityA(EntityType): |
83 relationa2b = SubjectRelation('EntityB') |
85 relation_a2b = SubjectRelation('EntityB') |
84 |
86 |
85 class EntityB(EntityType): |
87 class EntityB(EntityType): |
86 pass |
88 pass |
87 |
89 |
88 May generate the following message :: |
90 May generate the following message :: |
89 |
91 |
90 add Execution has_export File subject |
92 add EntityA relation_a2b EntityB subject |
91 |
93 |
92 This message will be used in views of ``EntityA`` for creation of a new |
94 This message will be used in views of ``EntityA`` for creation of a new |
93 ``EntityB`` with a preset relation ``relation_a2b`` between the current |
95 ``EntityB`` with a preset relation ``relation_a2b`` between the current |
94 ``EntityA`` and the new ``EntityB``. The opposite message :: |
96 ``EntityA`` and the new ``EntityB``. The opposite message :: |
95 |
97 |
96 add Execution has_export File object |
98 add EntityA relation_a2b EntityB object |
97 |
99 |
98 Is used for similar creation of an ``EntityA`` from a view of ``EntityB``. The |
100 Is used for similar creation of an ``EntityA`` from a view of ``EntityB``. The |
99 title of they respective creation form will be :: |
101 title of they respective creation form will be :: |
100 |
102 |
101 creating EntityB (EntityA %(linkto)s relation_a2b EntityB) |
103 creating EntityB (EntityA %(linkto)s relation_a2b EntityB) |
103 creating EntityA (EntityA relation_a2b %(linkto)s EntityA) |
105 creating EntityA (EntityA relation_a2b %(linkto)s EntityA) |
104 |
106 |
105 In the translated string you can use ``%(linkto)s`` for reference to the source |
107 In the translated string you can use ``%(linkto)s`` for reference to the source |
106 ``entity``. |
108 ``entity``. |
107 |
109 |
108 Handle the translation catalog |
110 Handling the translation catalog |
109 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
111 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
110 |
112 |
111 Once the internationalization is done in your code, you need to populate and |
113 Once the internationalization is done in your code, you need to populate and |
112 update the translation catalog. Cubicweb provides the following commands for this |
114 update the translation catalog. Cubicweb provides the following commands for this |
113 purpose: |
115 purpose: |
114 |
116 |
115 |
117 |
116 * `i18ncubicweb` updates Cubicweb framework's translation |
118 * `i18ncubicweb` updates Cubicweb framework's translation |
117 catalogs. Unless you actually work on the framework itself, you |
119 catalogs. Unless you actually work on the framework itself, you |
118 don't need to use this command. |
120 don't need to use this command. |
119 |
121 |
120 * `i18ncube` updates the translation catalogs of *one particular |
122 * `i18ncube` updates the translation catalogs of *one particular cube* |
121 cube* (or of all cubes). After this command is |
123 (or of all cubes). After this command is executed you must update |
122 executed you must update the translation files *.po* in the "i18n" |
124 the translation files *.po* in the "i18n" directory of your |
123 directory of your template. This command will of course not remove |
125 cube. This command will of course not remove existing translations |
124 existing translations still in use. |
126 still in use. It will mark unused translation but not remove them. |
125 |
127 |
126 * `i18ninstance` recompiles the translation catalogs of *one particular |
128 * `i18ninstance` recompiles the translation catalogs of *one particular |
127 instance* (or of all instances) after the translation catalogs of |
129 instance* (or of all instances) after the translation catalogs of |
128 its cubes have been updated. This command is automatically |
130 its cubes have been updated. This command is automatically |
129 called every time you create or update your instance. The compiled |
131 called every time you create or update your instance. The compiled |
132 for exemple). |
134 for exemple). |
133 |
135 |
134 |
136 |
135 Example |
137 Example |
136 ``````` |
138 ``````` |
|
139 |
137 You have added and/or modified some translation strings in your cube |
140 You have added and/or modified some translation strings in your cube |
138 (after creating a new view or modifying the cube's schema for exemple). |
141 (after creating a new view or modifying the cube's schema for exemple). |
139 To update the translation catalogs you need to do: |
142 To update the translation catalogs you need to do: |
140 |
143 |
141 1. `cubicweb-ctl i18ncube <cube>` |
144 1. `cubicweb-ctl i18ncube <cube>` |
142 2. Edit the <cube>/i18n/xxx.po files and add missing translations (empty `msgstr`) |
145 2. Edit the <cube>/i18n/xxx.po files and add missing translations (empty `msgstr`) |
143 3. `hg ci -m "updated i18n catalogs"` |
146 3. `hg ci -m "updated i18n catalogs"` |
144 4. `cubicweb-ctl i18ninstance <myinstance>` |
147 4. `cubicweb-ctl i18ninstance <myinstance>` |
145 |
148 |
|
149 Editing po files |
|
150 ~~~~~~~~~~~~~~~~ |
|
151 |
|
152 Using a PO aware editor |
|
153 ```````````````````````` |
|
154 |
|
155 Many tools exist to help maintain .po (PO) files. Common editors or |
|
156 development environment provides modes for these. One can also find |
|
157 dedicated PO files editor, such as `poedit`_. |
|
158 |
|
159 .. _`poedit`: http://www.poedit.net/ |
|
160 |
|
161 While usage of such a tool is commendable, PO files are perfectly |
|
162 editable with a (unicode aware) plain text editor. It is also useful |
|
163 to know their structure for troubleshooting purposes. |
|
164 |
|
165 Structure of a PO file |
|
166 `````````````````````` |
|
167 |
|
168 In this section, we selectively quote passages of the `GNU gettext`_ |
|
169 manual chapter on PO files, available there:: |
|
170 |
|
171 http://www.gnu.org/software/hello/manual/gettext/PO-Files.html |
|
172 |
|
173 One PO file entry has the following schematic structure:: |
|
174 |
|
175 white-space |
|
176 # translator-comments |
|
177 #. extracted-comments |
|
178 #: reference... |
|
179 #, flag... |
|
180 #| msgid previous-untranslated-string |
|
181 msgid untranslated-string |
|
182 msgstr translated-string |
|
183 |
|
184 |
|
185 A simple entry can look like this:: |
|
186 |
|
187 #: lib/error.c:116 |
|
188 msgid "Unknown system error" |
|
189 msgstr "Error desconegut del sistema" |
|
190 |
|
191 It is also possible to have entries with a context specifier. They |
|
192 look like this:: |
|
193 |
|
194 white-space |
|
195 # translator-comments |
|
196 #. extracted-comments |
|
197 #: reference... |
|
198 #, flag... |
|
199 #| msgctxt previous-context |
|
200 #| msgid previous-untranslated-string |
|
201 msgctxt context |
|
202 msgid untranslated-string |
|
203 msgstr translated-string |
|
204 |
|
205 |
|
206 The context serves to disambiguate messages with the same |
|
207 untranslated-string. It is possible to have several entries with the |
|
208 same untranslated-string in a PO file, provided that they each have a |
|
209 different context. Note that an empty context string and an absent |
|
210 msgctxt line do not mean the same thing. |
|
211 |
|
212 Contexts and CubicWeb |
|
213 ````````````````````` |
|
214 |
|
215 CubicWeb PO files have both non-contextual and contextual msgids. |
|
216 |
|
217 Contextual entries are automatically used in some cases. For instance, |
|
218 entity.dc_type(), eschema.display_name(req) or display_name(etype, |
|
219 req, form, context) methods/function calls will use them. |
|
220 |
|
221 It is also possible to explicitly use the with _cw.pgettext(context, |
|
222 msgid). |