OLD | NEW |
| (Empty) |
1 <!-- | |
2 [NOTEs for editors: | |
3 * Try to be consistent about string vs. message (it's probably not yet). | |
4 --> | |
5 <!-- BEGIN AUTHORED CONTENT --> | |
6 <p id="classSummary"> | |
7 An <em>internationalized</em> extension | |
8 can be easily | |
9 <em>localized</em> — | |
10 adapted to languages and regions | |
11 that it didn't originally support. | |
12 </p> | |
13 <p> | |
14 To internationalize your extension, | |
15 you need to put all of its user-visible strings into a file | |
16 named <a href="i18n-messages.html"><code>messages.json</code></a>. | |
17 Each time you localize your extension | |
18 you add a messages file | |
19 under a directory | |
20 named <code>_locales/<em>localeCode</em></code>, | |
21 where <em>localeCode</em> is a code such as | |
22 <code>en</code> for English. | |
23 </p> | |
24 <p> | |
25 Here's the file hierarchy | |
26 for an internationalized extension that supports | |
27 English (<code>en</code>), | |
28 Spanish (<code>es</code>), and | |
29 Korean (<code>ko</code>): | |
30 </p> | |
31 <img src="{{static}}/images/i18n-hierarchy.gif" | |
32 alt='In the extension directory: manifest.json, *.html, *.js, _locales director
y. In the _locales directory: en, es, and ko directories, each with a messages.j
son file.' | |
33 width="385" height="77" /> | |
34 <h2 id="l10">How to support multiple languages</h2> | |
35 <p> | |
36 Say you have an extension | |
37 with the files shown in the following figure: | |
38 </p> | |
39 <img src="{{static}}/images/i18n-before.gif" | |
40 alt='A manifest.json file and a file with JavaScript. The .json file has "name"
: "Hello World". The JavaScript file has title = "Hello World";' | |
41 width="323" height="148"> | |
42 <p> | |
43 To internationalize this extension, | |
44 you name each user-visible string | |
45 and put it into a messages file. | |
46 The extension's manifest, | |
47 CSS files, | |
48 and JavaScript code | |
49 use each string's name to get its localized version. | |
50 </p> | |
51 <p> | |
52 Here's what the extension looks like when it's internationalized | |
53 (note that it still has only English strings): | |
54 </p> | |
55 <img src="{{static}}/images/i18n-after-1.gif" | |
56 alt='In the manifest.json file, "Hello World" has been changed to "__MSG_extNam
e__", and a new "default_locale" item has the value "en". In the JavaScript file
, "Hello World" has been changed to chrome.i18n.getMessage("extName"). A new fil
e named _locales/en/messages.json defines "extName".' | |
57 width="782" height="228"> | |
58 <p class="note"> | |
59 <b>Important:</b> | |
60 If an extension has a <code>_locales</code> directory, | |
61 the <a href="manifest.html">manifest</a> | |
62 <b>must</b> define "default_locale". | |
63 </p> | |
64 <p> | |
65 Some notes about internationalizing extensions: | |
66 </p> | |
67 <ul> | |
68 <li><p> | |
69 You can use any of the <a href="#overview-locales">supported locales</a>. | |
70 If you use an unsupported locale, | |
71 Google Chrome ignores it. | |
72 </p></li> | |
73 <li> | |
74 In <code>manifest.json</code> | |
75 and CSS files, | |
76 refer to a string named <em>messagename</em> like this: | |
77 <pre>__MSG_<em>messagename</em>__</pre> | |
78 </li> | |
79 <li> | |
80 In your extension's JavaScript code, | |
81 refer to a string named <em>messagename</em> | |
82 like this: | |
83 <pre>chrome.i18n.getMessage("<em>messagename</em>")</pre> | |
84 <li> <p> | |
85 In each call to <code>getMessage()</code>, | |
86 you can supply up to 9 strings | |
87 to be included in the message. | |
88 See <a href="#examples-getMessage">Examples: getMessage</a> | |
89 for details. | |
90 </p> | |
91 </li> | |
92 <li><p> | |
93 Some messages, such as <code>@@bidi_dir</code> and <code>@@ui_locale</code>, | |
94 are provided by the internationalization system. | |
95 See the <a href="#overview-predefined">Predefined messages</a> section | |
96 for a full list of predefined message names. | |
97 </p> | |
98 </li> | |
99 <li> | |
100 In <code>messages.json</code>, | |
101 each user-visible string has a name, a "message" item, | |
102 and an optional "description" item. | |
103 The name is a key | |
104 such as "extName" or "search_string" | |
105 that identifies the string. | |
106 The "message" specifies | |
107 the value of the string in this locale. | |
108 The optional "description" | |
109 provides help to translators, | |
110 who might not be able to see how the string is used in your extension. | |
111 For example: | |
112 <pre> | |
113 { | |
114 "search_string": { | |
115 "message": "hello%20world", | |
116 "description": "The string we search for. Put %20 between words that go toge
ther." | |
117 }, | |
118 ... | |
119 }</pre> | |
120 <p> | |
121 For more information, see | |
122 <a href="i18n-messages.html">Formats: Locale-Specific Messages</a>. | |
123 </p> | |
124 </li> | |
125 </ul> | |
126 <p> | |
127 Once an extension is internationalized, | |
128 translating it is simple. | |
129 You copy <code>messages.json</code>, | |
130 translate it, | |
131 and put the copy into a new directory under <code>_locales</code>. | |
132 For example, to support Spanish, | |
133 just put a translated copy of <code>messages.json</code> | |
134 under <code>_locales/es</code>. | |
135 The following figure shows the previous extension | |
136 with a new Spanish translation. | |
137 </p> | |
138 <img src="{{static}}/images/i18n-after-2.gif" | |
139 alt='This looks the same as the previous figure, but with a new file at _locale
s/es/messages.json that contains a Spanish translation of the messages.' | |
140 width="782" height="358"> | |
141 <h2 id="overview-predefined">Predefined messages</h2> | |
142 <p> | |
143 The internationalization system provides a few predefined | |
144 messages to help you localize your extension. | |
145 These include <code>@@ui_locale</code>, | |
146 so you can detect the current UI locale, | |
147 and a few <code>@@bidi_...</code> messages | |
148 that let you detect the text direction. | |
149 The latter messages have similar names to constants in the | |
150 <a href="http://code.google.com/apis/gadgets/docs/i18n.html#BIDI"> | |
151 gadgets BIDI (bi-directional) API</a>. | |
152 </p> | |
153 <p> | |
154 The special message <code>@@extension_id</code> | |
155 can be used in the CSS and JavaScript files of any extension, | |
156 whether or not the extension is localized. | |
157 This message doesn't work in manifest files. | |
158 </p> | |
159 <p> | |
160 The following table describes each predefined message. | |
161 </p> | |
162 <table> | |
163 <tr> | |
164 <th>Message name</th> <th>Description</th> | |
165 </tr> | |
166 <tr> | |
167 <td> <code>@@extension_id</code> </td> | |
168 <td>The extension ID; | |
169 you might use this string to construct URLs | |
170 for resources inside the extension. | |
171 Even unlocalized extensions can use this message. | |
172 <br> | |
173 <b>Note:</b> You can't use this message in a manifest file. | |
174 </td> | |
175 </tr> | |
176 <tr> | |
177 <td> <code>@@ui_locale</code> </td> | |
178 <td>The current locale; | |
179 you might use this string to construct locale-specific URLs. </td> | |
180 </tr> | |
181 <tr> | |
182 <td> <code>@@bidi_dir</code> </td> | |
183 <td> The text direction for the current locale, | |
184 either "ltr" for left-to-right languages such as English | |
185 or "rtl" for right-to-left languages such as Japanese. </td> | |
186 </tr> | |
187 <tr> | |
188 <td> <code>@@bidi_reversed_dir</code> </td> | |
189 <td> If the <code>@@bidi_dir</code> is "ltr", then this is "rtl"; | |
190 otherwise, it's "ltr". </td> | |
191 </tr> | |
192 <tr> | |
193 <td> <code>@@bidi_start_edge</code> </td> | |
194 <td> If the <code>@@bidi_dir</code> is "ltr", then this is "left"; | |
195 otherwise, it's "right". </td> | |
196 </tr> | |
197 <tr> | |
198 <td> <code>@@bidi_end_edge</code> </td> | |
199 <td> If the <code>@@bidi_dir</code> is "ltr", then this is "right"; | |
200 otherwise, it's "left". </td> | |
201 </tr> | |
202 </table> | |
203 <p> | |
204 Here's an example of using <code>@@extension_id</code> in a CSS file | |
205 to construct a URL: | |
206 </p> | |
207 <pre> | |
208 body { | |
209 <b>background-image:url('chrome-extension://__MSG_@@extension_id__/background.
png');</b> | |
210 } | |
211 </pre> | |
212 <p> | |
213 If the extension ID is abcdefghijklmnopqrstuvwxyzabcdef, | |
214 then the bold line in the previous code snippet becomes: | |
215 </p> | |
216 <pre> | |
217 background-image:url('chrome-extension://abcdefghijklmnopqrstuvwxyzabcdef/backgr
ound.png'); | |
218 </pre> | |
219 <p> | |
220 Here's an example of using <code>@@bidi_*</code> messages in a CSS file: | |
221 </p> | |
222 <pre> | |
223 body { | |
224 <b>direction: __MSG_@@bidi_dir__;</b> | |
225 } | |
226 div#header { | |
227 margin-bottom: 1.05em; | |
228 overflow: hidden; | |
229 padding-bottom: 1.5em; | |
230 <b>padding-__MSG_@@bidi_start_edge__: 0;</b> | |
231 <b>padding-__MSG_@@bidi_end_edge__: 1.5em;</b> | |
232 position: relative; | |
233 } | |
234 </pre> | |
235 <p> | |
236 For left-to-right languages such as English, | |
237 the bold lines become: | |
238 </p> | |
239 <pre> | |
240 dir: ltr; | |
241 padding-left: 0; | |
242 padding-right: 1.5em; | |
243 </pre> | |
244 <h2 id="overview-locales">Locales</h2> | |
245 <p> | |
246 You can choose from many locales, | |
247 including some (such as <code>en</code>) | |
248 that let a single translation support multiple variations of a language | |
249 (such as <code>en_GB</code> and <code>en_US</code>). | |
250 </p> | |
251 <h3 id="locales-supported">Supported locales</h3> | |
252 <p> | |
253 Extensions can use any of the | |
254 <a href="http://code.google.com/chrome/webstore/docs/i18n.html#localeTable">loca
les that the Chrome Web Store supports</a>. | |
255 </p> | |
256 <h3 id="locales-usage">How extensions find strings</h3> | |
257 <p> | |
258 You don't have to define every string for every locale | |
259 that your internationalized extension supports. | |
260 As long as the default locale's <code>messages.json</code> file | |
261 has a value for every string, | |
262 your extension will run no matter how sparse a translation is. | |
263 Here's how the extension system searches for a message: | |
264 </p> | |
265 <ol> | |
266 <li> | |
267 Search the messages file (if any) | |
268 for the user's preferred locale. | |
269 For example, when Google Chrome's locale is set to | |
270 British English (<code>en_GB</code>), | |
271 the system first looks for the message in | |
272 <code>_locales/en_GB/messages.json</code>. | |
273 If that file exists and the message is there, | |
274 the system looks no further. | |
275 </li> | |
276 <li> | |
277 If the user's preferred locale has a region | |
278 (that is, the locale has an underscore: _), | |
279 search the locale without that region. | |
280 For example, if the <code>en_GB</code> messages file | |
281 doesn't exist or doesn't contain the message, | |
282 the system looks in the <code>en</code> messages file. | |
283 If that file exists and the message is there, | |
284 the system looks no further. | |
285 </li> | |
286 <li> | |
287 Search the messages file for the extension's default locale. | |
288 For example, if the extension's "default_locale" is set to "es", | |
289 and neither <code>_locales/en_GB/messages.json</code> | |
290 nor <code>_locales/en/messages.json</code> contains the message, | |
291 the extension uses the message from | |
292 <code>_locales/es/messages.json</code>. | |
293 </li> | |
294 </ol> | |
295 <p> | |
296 In the following figure, | |
297 the message named "colores" is in all three locales | |
298 that the extension supports, | |
299 but "extName" is in only two of the locales. | |
300 Wherever a user running Google Chrome in US English sees the label "Colors", | |
301 a user of British English sees "Colours". | |
302 Both US English and British English users | |
303 see the extension name "Hello World". | |
304 Because the default language is Spanish, | |
305 users running Google Chrome in any non-English language | |
306 see the label "Colores" and the extension name "Hola mundo". | |
307 </p> | |
308 <img src="{{static}}/images/i18n-strings.gif" | |
309 alt='Four files: manifest.json and three messages.json files (for es, en, and e
n_GB). The es and en files show entries for messages named "extName" and "color
es"; the en_GB file has just one entry (for "colores").' | |
310 width="493" height="488" /> | |
311 <h3 id="locales-testing">How to set your browser's locale</h3> | |
312 <p> | |
313 To test translations, you might want to set your browser's locale. | |
314 This section tells you how to set the locale in | |
315 <a href="#testing-win">Windows</a>, | |
316 <a href="#testing-mac">Mac OS X</a>, and | |
317 <a href="#testing-linux">Linux</a>. | |
318 </p> | |
319 <h4 id="testing-win">Windows</h4> | |
320 <p> | |
321 You can change the locale using either | |
322 a locale-specific shortcut | |
323 or the Google Chrome UI. | |
324 The shortcut approach is quicker, once you've set it up, | |
325 and it lets you use several languages at once. | |
326 </p> | |
327 <h5 id="win-shortcut">Using a locale-specific shortcut</h5> | |
328 <p> | |
329 To create and use a shortcut that launches Google Chrome | |
330 with a particular locale: | |
331 </p> | |
332 <ol> | |
333 <li> | |
334 Make a copy of the Google Chrome shortcut | |
335 that's already on your desktop. | |
336 </li> | |
337 <li> | |
338 Rename the new shortcut to match the new locale. | |
339 </li> | |
340 <li> | |
341 Change the shortcut's properties | |
342 so that the Target field specifies the | |
343 <code>--lang</code> and | |
344 <code>--user-data-dir</code> flags. | |
345 The target should look something like this: | |
346 <pre><em>path_to_chrome.exe</em> --lang=<em>locale</em> --user-data-dir=c:\<em>l
ocale_profile_dir</em></pre> | |
347 </li> | |
348 <li> | |
349 Launch Google Chrome by double-clicking the shortcut. | |
350 </li> | |
351 </ol> | |
352 <p> | |
353 For example, to create a shortcut | |
354 that launches Google Chrome in Spanish (<code>es</code>), | |
355 you might create a shortcut named <code>chrome-es</code> | |
356 that has the following target: | |
357 </p> | |
358 <pre><em>path_to_chrome.exe</em> --lang=es --user-data-dir=c:\chrome-profile-es<
/pre> | |
359 <p> | |
360 You can create as many shortcuts as you like, | |
361 making it easy to test your extension in multiple languages. | |
362 For example: | |
363 </p> | |
364 <pre><em>path_to_chrome.exe</em> --lang=en --user-data-dir=c:\chrome-profile-en | |
365 <em>path_to_chrome.exe</em> --lang=en_GB --user-data-dir=c:\chrome-profile-en_GB | |
366 <em>path_to_chrome.exe</em> --lang=ko --user-data-dir=c:\chrome-profile-ko</pre> | |
367 <p class="note"> | |
368 <b>Note:</b> | |
369 Specifying <code>--user-data-dir</code> is optional but handy. | |
370 Having one data directory per locale | |
371 lets you run the browser | |
372 in several languages at the same time. | |
373 A disadvantage is that because the locales' data isn't shared, | |
374 you have to install your extension multiple times — once per locale, | |
375 which can be challenging when you don't speak the language. | |
376 For more information, see | |
377 <a href="http://www.chromium.org/developers/creating-and-using-profiles">Creatin
g and Using Profiles</a>. | |
378 </p> | |
379 <h5 id="win-ui">Using the UI</h5> | |
380 <p> | |
381 Here's how to change the locale using the UI on Google Chrome for Windows: | |
382 </p> | |
383 <ol> | |
384 <li> Wrench icon > <b>Options</b> </li> | |
385 <li> Choose the <b>Under the Hood</b> tab </li> | |
386 <li> Scroll down to <b>Web Content</b> </li> | |
387 <li> Click <b>Change font and language settings</b> </li> | |
388 <li> Choose the <b>Languages</b> tab </li> | |
389 <li> Use the drop down to set the <b>Google Chrome language</b> </li> | |
390 <li> Restart Chrome </li> | |
391 </ol> | |
392 <h4 id="testing-mac">Mac OS X</h4> | |
393 <p> | |
394 To change the locale on Mac, | |
395 you use the system preferences. | |
396 </p> | |
397 <ol> | |
398 <li> From the Apple menu, choose <b>System Preferences</b> </li> | |
399 <li> Under the <b>Personal</b> section, choose <b>International</b> </li> | |
400 <li> Choose your language and location </li> | |
401 <li> Restart Chrome </li> | |
402 </ol> | |
403 <h4 id="testing-linux">Linux</h4> | |
404 <p> | |
405 To change the locale on Linux, | |
406 first quit Google Chrome. | |
407 Then, all in one line, | |
408 set the LANGUAGE environment variable | |
409 and launch Google Chrome. | |
410 For example: | |
411 </p> | |
412 <pre> | |
413 LANGUAGE=es ./chrome | |
414 </pre> | |
415 <h2 id="overview-examples">Examples</h2> | |
416 <p> | |
417 You can find simple examples of internationalization in the | |
418 <a href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extension
s/docs/examples/api/i18n/">examples/api/i18n</a> | |
419 directory. | |
420 For a complete example, see | |
421 <a href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extension
s/docs/examples/extensions/news/">examples/extensions/news</a>. | |
422 For other examples and for help in viewing the source code, see | |
423 <a href="samples.html">Samples</a>. | |
424 </p> | |
425 <h3 id="examples-getMessage">Examples: getMessage</h3> | |
426 <!-- | |
427 [PENDING: improve this section. it should probably start with a | |
428 one-variable example that includes the messages.json code.] | |
429 --> | |
430 <p> | |
431 The following code gets a localized message from the browser | |
432 and displays it as a string. | |
433 It replaces two placeholders within the message with the strings | |
434 "string1" and "string2". | |
435 </p> | |
436 <pre> | |
437 function getMessage() { | |
438 var message = chrome.i18n.getMessage("click_here", ["string1", "string2"]); | |
439 document.getElementById("languageSpan").innerHTML = message; | |
440 } | |
441 </pre> | |
442 <p> | |
443 Here's how you'd supply and use a single string: | |
444 </p> | |
445 <pre> | |
446 <em>// In JavaScript code</em> | |
447 status.innerText = chrome.i18n.getMessage("error", errorDetails); | |
448 <em>// In messages.json</em> | |
449 "error": { | |
450 "message": "Error: $details$", | |
451 "description": "Generic error template. Expects error parameter to be passed i
n.", | |
452 "placeholders": { | |
453 "details": { | |
454 "content": "$1", | |
455 "example": "Failed to fetch RSS feed." | |
456 } | |
457 } | |
458 } | |
459 </pre> | |
460 <p> | |
461 For more information about placeholders, see the | |
462 <a href="i18n-messages.html">Locale-Specific Messages</a> page. | |
463 For details on calling <code>getMessage()</code>, see the | |
464 <a href="#method-getMessage">API reference</a>. | |
465 </p> | |
466 <h3 id="example-accept-languages">Example: getAcceptLanguages</h3> | |
467 <p> | |
468 The following code gets accept-languages from the browser and displays them as a | |
469 string by separating each accept-language with ','. | |
470 </p> | |
471 <pre> | |
472 function getAcceptLanguages() { | |
473 chrome.i18n.getAcceptLanguages(function(languageList) { | |
474 var languages = languageList.join(","); | |
475 document.getElementById("languageSpan").innerHTML = languages; | |
476 }) | |
477 } | |
478 </pre> | |
479 <p> | |
480 For details on calling <code>getAcceptLanguages()</code>, see the | |
481 <a href="#method-getAcceptLanguages">API reference</a>. | |
482 </p> | |
483 <!-- END AUTHORED CONTENT --> | |
OLD | NEW |