OLD | NEW |
1 <div id="pageData-name" class="pageData">i18n</div> | 1 <div id="pageData-name" class="pageData">Internationalization (i18n)</div> |
2 | 2 |
| 3 <!-- |
| 4 [NOTEs for editors: |
| 5 * Try to be consistent about string vs. message |
| 6 --> |
| 7 |
3 <!-- BEGIN AUTHORED CONTENT --> | 8 <!-- BEGIN AUTHORED CONTENT --> |
4 <p id="classSummary"> | 9 <p id="classSummary"> |
5 Use the <code>chrome.i18n</code> module to manipulate the i18n related browser | 10 Use the <code>chrome.i18n</code> module to |
6 settings, such as the accept languages. | 11 get localized messages for the current locale, |
7 <!-- [PENDING: add when getMessage works: "or to get localized messages for the
current locale."] --> | 12 from either the extension or its content script. |
8 </p> | 13 You can also use this module to get the languages that the browser accepts. |
| 14 </p> |
| 15 |
| 16 <h2 id="l10">How to support multiple languages</h2> |
| 17 |
| 18 <p> |
| 19 To simplify translating your extension, |
| 20 <em>internationalize</em> it by |
| 21 putting all its user-visible strings |
| 22 in a file named <code>messages.json</code>. |
| 23 For example, let's say you have an extension |
| 24 with the files shown in the following figure: |
| 25 </p> |
| 26 |
| 27 <img src="images/i18n-before.gif" alt="" |
| 28 width="" height=""> |
| 29 |
| 30 <p> |
| 31 To internationalize this extension, |
| 32 put each user-visible string into a messages file. |
| 33 For an extension that's in English, |
| 34 the messages file can be at |
| 35 <code>_locales/en/messages.json</code>. |
| 36 Each message has a name. |
| 37 The extension's manifest and JavaScript code |
| 38 use this name to get the localized message. |
| 39 </p> |
| 40 |
| 41 <p> |
| 42 The next figure shows an internationalized extension |
| 43 that has only English strings. |
| 44 </p> |
| 45 |
| 46 <img src="images/i18n-after-1.gif" alt="" |
| 47 width="" height=""> |
| 48 |
| 49 <p class="note"> |
| 50 <b>Important:</b> |
| 51 If an extension has a <code>_locales</code> directory, |
| 52 the <a href="manifest.html">manifest</a> |
| 53 <b>must</b> define "default_locale". |
| 54 </p> |
| 55 |
| 56 <p> |
| 57 Once an extension is internationalized, |
| 58 translating it is simple. |
| 59 You just copy <code>messages.json</code>, |
| 60 translate it, |
| 61 and put the copy into a new directory under <code>_locales</code>. |
| 62 For example, to support Spanish, |
| 63 just put the translated copy of <code>messages.json</code> |
| 64 under <code>_locales/es</code>. |
| 65 The following figure shows the extension with a new Spanish translation. |
| 66 </p> |
| 67 |
| 68 <img src="images/i18n-after-2.gif" alt="" |
| 69 width="" height=""> |
| 70 |
| 71 <p> |
| 72 Some notes about internationalizing extensions: |
| 73 </p> |
| 74 |
| 75 <ul> |
| 76 <li><p> |
| 77 Use only <a href="#overview-locales">supported locales</a>! |
| 78 </p></li> |
| 79 |
| 80 <li> |
| 81 In <code>manifest.json</code>, |
| 82 refer to a string named <em>messagename</em> like this: |
| 83 <pre>__MSG_<em>messagename</em>__</pre> |
| 84 </li> |
| 85 |
| 86 <li> |
| 87 In your extension's JavaScript code, |
| 88 refer to a string named <em>messagename</em> |
| 89 like this: |
| 90 <pre>chrome.i18n.getMessage("<em>messagename</em>")</pre> |
| 91 |
| 92 <li> <p> |
| 93 In each call to <code>getMessage()</code>, |
| 94 you can supply up to 9 strings |
| 95 to be included in the message. |
| 96 See <a href="#examples-getMessage">Examples: getMessage</a> |
| 97 for details. |
| 98 </p> |
| 99 </li> |
| 100 |
| 101 <li> |
| 102 In <code>messages.json</code>, |
| 103 each user-visible string has a name, a "message" item, |
| 104 and an optional "description" item. |
| 105 The name is a key |
| 106 such as "extName" or "search_string" |
| 107 that identifies the string. |
| 108 The "message" specifies |
| 109 the value of the string in this locale. |
| 110 The optional "description" |
| 111 provides help to translators, |
| 112 who might not be able to see how the string is used in your extension. |
| 113 For example: |
| 114 <pre> |
| 115 { |
| 116 "search_string": { |
| 117 "message": "hello%20world", |
| 118 "description": "The string we search for. Put %20 between words that go toge
ther." |
| 119 }, |
| 120 ... |
| 121 }</pre> |
| 122 </li> |
| 123 |
| 124 </ul> |
| 125 |
| 126 <!-- |
| 127 For more information, see |
| 128 <a href="message.html">Formats: Message Files</a>. |
| 129 [PENDING: write this page!] |
| 130 --> |
| 131 |
| 132 <h2 id="overview-locales">Locales</h2> |
| 133 |
| 134 <p> |
| 135 Extensions can use all the locales that Google Chrome supports, |
| 136 plus a few (such as <code>en</code>) |
| 137 that let a single translation support multiple variations of a language |
| 138 (such as <code>en_GB</code> and <code>en_US</code>). |
| 139 </p> |
| 140 |
| 141 |
| 142 <h3 id="locales-supported">Supported locales</h3> |
| 143 |
| 144 <p> |
| 145 Your extension can use any of the following locales: |
| 146 </p> |
| 147 |
| 148 <p> |
| 149 <code>am ar bg bn ca cs da de el en en_GB en_US es es_419 et fi
fil fr gu he hi hr hu id it ja kn ko lt |
| 150 lv ml mr nb nl or pl pt pt_BR pt_PT ro ru sk sl sr sv sw ta te
th tr uk vi zh zh_CN zh_TW</code> |
| 151 </p> |
| 152 |
| 153 |
| 154 <h3 id="locales-usage">How extensions find strings</h3> |
| 155 |
| 156 <p> |
| 157 You don't have to define every string for every locale |
| 158 that your internationalized extension supports. |
| 159 As long as the default locale's <code>messages.json</code> file |
| 160 has a value for every string, |
| 161 your extension will run no matter how sparse a translation is. |
| 162 Here's how the extension system searches for a message: |
| 163 </p> |
| 164 |
| 165 <ol> |
| 166 <li> |
| 167 Search the messages file (if any) |
| 168 for the user's preferred locale. |
| 169 For example, when Google Chrome's locale is set to |
| 170 British English (<code>en_GB</code>), |
| 171 the system first looks for the message in |
| 172 <code>_locales/en_GB/messages.json</code>. |
| 173 If that file exists and the message is there, |
| 174 the system looks no further. |
| 175 </li> |
| 176 <li> |
| 177 If the user's preferred locale has a region |
| 178 (that is, the locale has an underscore: _), |
| 179 search the locale without that region. |
| 180 For example, if the <code>en_GB</code> messages file |
| 181 doesn't exist or doesn't contain the message, |
| 182 the system looks in the <code>en</code> messages file. |
| 183 If that file exists and the message is there, |
| 184 the system looks no further. |
| 185 </li> |
| 186 <li> |
| 187 Search the messages file for the extension's default locale. |
| 188 For example, if the extension's "default_locale" is set to "es", |
| 189 and neither <code>_locales/en_GB/messages.json</code> |
| 190 nor <code>_locales/en/messages.json</code> contains the message, |
| 191 the extension uses the message from |
| 192 <code>_locales/es/messages.json</code>. |
| 193 </li> |
| 194 </ol> |
| 195 |
| 196 <p> |
| 197 In the following figure, |
| 198 the message named "color" is in all three locales |
| 199 that the extension supports, |
| 200 but "extName" is in only two of the locales. |
| 201 Where a user running Google Chrome in US English sees the heading "Color", |
| 202 a user running it in British English sees "Colour". |
| 203 Both US English and British English users |
| 204 see the extension name "Hello World". |
| 205 Because the default language is Spanish, |
| 206 users running Google Chrome in any non-English language |
| 207 see the heading "Color" and the extension name "Hola mundo". |
| 208 </p> |
| 209 |
| 210 <img src="images/i18n-strings.gif" alt="" |
| 211 width="496" height="490" /> |
| 212 |
| 213 <h3 id="locales-testing">How to set your browser's locale</h3> |
| 214 |
| 215 <p> |
| 216 When you test translations, you might want to set your browser's locale. |
| 217 Here's how. |
| 218 </p> |
| 219 |
| 220 <h4 id="testing-win">Windows</h4> |
| 221 |
| 222 <ol> |
| 223 <li> Tools menu (wrench) > <b>Options</b> </li> |
| 224 <li> Choose the <b>Under the Hood</b> tab </li> |
| 225 <li> Scroll down to <b>Web Content</b> </li> |
| 226 <li> Click <b>Change font and language settings</b> </li> |
| 227 <li> Choose the <b>Languages</b> tab </li> |
| 228 <li> Use the drop down to set the <b>Google Chrome language</b> </li> |
| 229 <li> Restart Chrome </li> |
| 230 </ol> |
| 231 |
| 232 <h4 id="testing-mac">Mac OS X</h4> |
| 233 |
| 234 <ol> |
| 235 <li> From the Apple menu, choose <b>System Preferences</b> </li> |
| 236 <li> Under the <b>Personal</b> section, choose <b>International</b> </li> |
| 237 <li> Choose your language and location </li> |
| 238 <li> Restart Chrome </li> |
| 239 </ol> |
| 240 |
| 241 <h4 id="testing-linux">Linux</h4> |
| 242 |
| 243 <p> |
| 244 Set the language environment variable, and then launch Google Chrome. |
| 245 For example: |
| 246 </p> |
| 247 |
| 248 <pre> |
| 249 LANGUAGE=es ./chrome |
| 250 </pre> |
| 251 |
9 | 252 |
10 <h2 id="overview-examples">Examples</h2> | 253 <h2 id="overview-examples">Examples</h2> |
11 | 254 |
12 <p> | 255 <p> |
| 256 You can find simple examples of internationalization in the |
| 257 <a href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extension
s/docs/examples/api/i18n/">examples/api/i18n</a> |
| 258 directory. |
| 259 For a more complete example, see |
| 260 <a href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extension
s/docs/examples/extensions/news_i18n/">examples/extensions/news_i18n</a> |
| 261 (compare it to |
| 262 <a href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extension
s/docs/examples/extensions/news/">examples/extensions/news</a>). |
| 263 For other examples and for help in viewing the source code, see |
| 264 <a href="samples.html">Samples</a>. |
| 265 </p> |
| 266 |
| 267 |
| 268 <h3 id="examples-getMessage">Examples: getMessage</h3> |
| 269 |
| 270 <!-- |
| 271 [PENDING: improve this section. it should probably start with a |
| 272 one-variable example that includes the messages.json code.] |
| 273 --> |
| 274 |
| 275 <p> |
| 276 The following code gets a localized message from the browser |
| 277 and displays it as a string. |
| 278 It replaces two placeholders within the message with the strings |
| 279 "string1" and "string2". |
| 280 </p> |
| 281 |
| 282 <pre> |
| 283 function getMessage() { |
| 284 var message = chrome.i18n.getMessage("click_here", ["string1", "string2"]); |
| 285 document.getElementById("languageSpan").innerHTML = message; |
| 286 } |
| 287 </pre> |
| 288 |
| 289 <p> |
| 290 Here's how you'd supply and use a single string: |
| 291 </p> |
| 292 |
| 293 <pre> |
| 294 <em>// In JavaScript code</em> |
| 295 status.innerText = chrome.i18n.getMessage("error", errorDetails); |
| 296 |
| 297 <em>// In messages.json</em> |
| 298 "error": { |
| 299 "message": "Error: $details$", |
| 300 "description": "Generic error template. Expects error parameter to be passed i
n.", |
| 301 "placeholders": { |
| 302 "details": { |
| 303 "content": "$1", |
| 304 "example": "Failed to fetch RSS feed." |
| 305 } |
| 306 } |
| 307 } |
| 308 </pre> |
| 309 |
| 310 <p> |
| 311 For more information about placeholders, |
| 312 see the <a href="http://dev.chromium.org/developers/design-documents/extensions/
i18n#TOC-Replacement-policy">internationalization design doc</a>. |
| 313 </p> |
| 314 |
| 315 <h3 id="example-accept-languages">Example: getAcceptLanguages</h3> |
| 316 <p> |
13 The following code gets accept-languages from the browser and displays them as a | 317 The following code gets accept-languages from the browser and displays them as a |
14 string by separating each accept-language with ','. | 318 string by separating each accept-language with ','. |
15 </p> | 319 </p> |
16 | 320 |
17 <pre> | 321 <pre> |
18 function getAcceptLanguages() { | 322 function getAcceptLanguages() { |
19 chrome.i18n.getAcceptLanguages(function(languageList) { | 323 chrome.i18n.getAcceptLanguages(function(languageList) { |
20 var languages = languageList.join(","); | 324 var languages = languageList.join(","); |
21 document.getElementById("languageSpan").innerHTML = languages; | 325 document.getElementById("languageSpan").innerHTML = languages; |
22 }) | 326 }) |
23 } | 327 } |
24 </pre> | 328 </pre> |
25 | 329 |
26 <!-- [PENDING: add the following when getMessage is working] | |
27 <p> | |
28 The following code gets a localized message from the browser and displays it as
a | |
29 string. It replaces two placeholders within the message with values arg1 and | |
30 arg2. | |
31 </p> | |
32 | |
33 <pre> | |
34 function getMessage() { | |
35 var message = chrome.i18n.getMessage("click_here", ["arg1", "arg2"]); | |
36 document.getElementById("languageSpan").innerHTML = message; | |
37 } | |
38 </pre> | |
39 --> | |
40 | |
41 <p> | |
42 You can find simple examples of internationalization in the | |
43 <a href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extension
s/docs/examples/api/i18n/">examples/api/i18n</a> | |
44 directory. | |
45 For other examples and for help in viewing the source code, see | |
46 <a href="samples.html">Samples</a>. | |
47 </p> | |
48 | |
49 <!-- END AUTHORED CONTENT --> | 330 <!-- END AUTHORED CONTENT --> |
OLD | NEW |