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 |