| OLD | NEW |
| 1 Intl | 1 Intl |
| 2 ==== | 2 ==== |
| 3 | 3 |
| 4 This package provides internationalization and localization facilities, | 4 This package provides internationalization and localization facilities, |
| 5 including message translation, plurals and genders, date/number formatting | 5 including message translation, plurals and genders, date/number formatting |
| 6 and parsing, and bidirectional text. | 6 and parsing, and bidirectional text. |
| 7 | 7 |
| 8 ## General | 8 ## General |
| 9 The most important library is [intl][intl_lib]. It defines the [Intl][Intl] | 9 The most important library is [intl][intl_lib]. It defines the [Intl][Intl] |
| 10 class, with the default locale and methods for accessing most of the | 10 class, with the default locale and methods for accessing most of the |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 ```dart | 45 ```dart |
| 46 var format = new DateFormat.yMd("ar"); | 46 var format = new DateFormat.yMd("ar"); |
| 47 var dateString = format.format(new DateTime.now()); | 47 var dateString = format.format(new DateTime.now()); |
| 48 ``` | 48 ``` |
| 49 | 49 |
| 50 or | 50 or |
| 51 | 51 |
| 52 ```dart | 52 ```dart |
| 53 print(myMessage(dateString, locale: 'ar'); | 53 print(myMessage(dateString, locale: 'ar'); |
| 54 ``` | 54 ``` |
| 55 » | 55 |
| 56 or | 56 or |
| 57 | 57 |
| 58 ```dart | 58 ```dart |
| 59 Intl.defaultLocale = "es"' | 59 Intl.defaultLocale = "es"; |
| 60 new DateFormat.jm().format(new DateTime.now()); | 60 new DateFormat.jm().format(new DateTime.now()); |
| 61 ``` | 61 ``` |
| 62 | 62 |
| 63 ## Initialization | 63 ## Initialization |
| 64 | 64 |
| 65 All the different types of locale data require an async initialization step | 65 All the different types of locale data require an async initialization step |
| 66 to make | 66 to make |
| 67 sure the data is available. This reduces the size of the application by only | 67 sure the data is available. This reduces the size of the application by only |
| 68 loading the | 68 loading the |
| 69 data that is actually required. | 69 data that is actually required. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 89 name: "continueMessage", | 89 name: "continueMessage", |
| 90 args: [], | 90 args: [], |
| 91 desc: "Explains that we will not proceed further until " | 91 desc: "Explains that we will not proceed further until " |
| 92 "the user presses a key"); | 92 "the user presses a key"); |
| 93 print(continueMessage()); | 93 print(continueMessage()); |
| 94 | 94 |
| 95 This provides, in addition to the basic message string, a name, a | 95 This provides, in addition to the basic message string, a name, a |
| 96 description for translators, the arguments used in the message, and | 96 description for translators, the arguments used in the message, and |
| 97 examples. The `name` and `args` parameters are required, and must | 97 examples. The `name` and `args` parameters are required, and must |
| 98 match the name (or ClassName_methodName) and arguments list of the | 98 match the name (or ClassName_methodName) and arguments list of the |
| 99 function respectively. In the future we | 99 function respectively. However, there is a transformer provided that |
| 100 hope to have these provided automatically. | 100 will automatically insert those parameters for you. In pubspec.yaml, |
| 101 add a section like |
| 101 | 102 |
| 102 This can be run in the program before any translation has been done, | 103 transformers: |
| 103 and will just return the message string. It can also be extracted to a | 104 - intl: |
| 104 file and then be made to return a translated version without modifying | 105 $include: some_file.dart |
| 105 the original program. See "Extracting Messages" below for more | 106 |
| 107 and then you can omit the name and args. |
| 108 |
| 109 A function with an Intl.message call can be run in the program before any |
| 110 translation has been done, and will just return the message string. It can also |
| 111 be extracted to a file and then be made to return a translated version without |
| 112 modifying the original program. See "Extracting Messages" below for more |
| 106 details. | 113 details. |
| 107 | 114 |
| 108 The purpose of wrapping the message in a function is to allow it to | 115 The purpose of wrapping the message in a function is to allow it to |
| 109 have parameters which can be used in the result. The message string is | 116 have parameters which can be used in the result. The message string is |
| 110 allowed to use a restricted form of Dart string interpolation, where | 117 allowed to use a restricted form of Dart string interpolation, where |
| 111 only the function's parameters can be used, and only in simple | 118 only the function's parameters can be used, and only in simple |
| 112 expressions. Local variables cannot be used, and neither can | 119 expressions. Local variables cannot be used, and neither can |
| 113 expressions with curly braces. Only the message string can have | 120 expressions with curly braces. Only the message string can have |
| 114 interpolation. The name, desc, args, and examples must be literals and | 121 interpolation. The name, desc, args, and examples must be literals and |
| 115 not contain interpolations. Only the args parameter can refer to | 122 not contain interpolations. Only the args parameter can refer to |
| 116 variables, and it should list exactly the function parameters. If you | 123 variables, and it should list exactly the function parameters. If you |
| 117 are passing numbers or dates and you want them formatted, you must do | 124 are passing numbers or dates and you want them formatted, you must do |
| 118 the formatting outside the function and pass the formatted string into | 125 the formatting outside the function and pass the formatted string into |
| 119 the message. | 126 the message. |
| 120 | 127 |
| 121 greetingMessage(name) => Intl.message( | 128 greetingMessage(name) => Intl.message( |
| 122 "Hello $name!", | 129 "Hello $name!", |
| 123 name: "greetingMessage", | 130 name: "greetingMessage", |
| 124 args: [name], | 131 args: [name], |
| 125 desc: "Greet the user as they first open the application", | 132 desc: "Greet the user as they first open the application", |
| 126 examples: {'name': "Emily"}); | 133 examples: const {'name': "Emily"}); |
| 127 print(greetingMessage('Dan')); | 134 print(greetingMessage('Dan')); |
| 128 | 135 |
| 129 There is one special class of complex expressions allowed in the | 136 There is one special class of complex expressions allowed in the |
| 130 message string, for plurals and genders. | 137 message string, for plurals and genders. |
| 131 | 138 |
| 132 remainingEmailsMessage(int howMany, String userName) => | 139 remainingEmailsMessage(int howMany, String userName) => |
| 133 Intl.message( | 140 Intl.message( |
| 134 "${Intl.plural(howMany, | 141 "${Intl.plural(howMany, |
| 135 zero: 'There are no emails left for $userName.', | 142 zero: 'There are no emails left for $userName.', |
| 136 one: 'There is one email left for $userName.', | 143 one: 'There is one email left for $userName.', |
| 137 other: 'There are $howMany emails left for $userName.')}", | 144 other: 'There are $howMany emails left for $userName.')}", |
| 138 name: "remainingEmailsMessage", | 145 name: "remainingEmailsMessage", |
| 139 args: [howMany, userName], | 146 args: [howMany, userName], |
| 140 desc: "How many emails remain after archiving.", | 147 desc: "How many emails remain after archiving.", |
| 141 examples: {'howMany': 42, 'userName': 'Fred'}); | 148 examples: const {'howMany': 42, 'userName': 'Fred'}); |
| 142 | 149 |
| 143 print(remainingEmailsMessage(1, "Fred")); | 150 print(remainingEmailsMessage(1, "Fred")); |
| 144 | 151 |
| 145 However, since the typical usage for a plural or gender is for it to | 152 However, since the typical usage for a plural or gender is for it to |
| 146 be at the top-level, we can also omit the [Intl.message][Intl.message] call and | 153 be at the top-level, we can also omit the [Intl.message][Intl.message] call and |
| 147 provide its parameters to the [Intl.plural][Intl.plural] call instead. | 154 provide its parameters to the [Intl.plural][Intl.plural] call instead. |
| 148 | 155 |
| 149 remainingEmailsMessage(int howMany, String userName) => | 156 remainingEmailsMessage(int howMany, String userName) => |
| 150 Intl.plural( | 157 Intl.plural( |
| 151 howMany, | 158 howMany, |
| 152 zero: 'There are no emails left for $userName.', | 159 zero: 'There are no emails left for $userName.', |
| 153 one: 'There is one email left for $userName.', | 160 one: 'There is one email left for $userName.', |
| 154 other: 'There are $howMany emails left for $userName.'), | 161 other: 'There are $howMany emails left for $userName.', |
| 155 name: "remainingEmailsMessage", | 162 name: "remainingEmailsMessage", |
| 156 args: [howMany, userName], | 163 args: [howMany, userName], |
| 157 desc: "How many emails remain after archiving.", | 164 desc: "How many emails remain after archiving.", |
| 158 examples: {'howMany': 42, 'userName': 'Fred'}); | 165 examples: const {'howMany': 42, 'userName': 'Fred'}); |
| 159 | 166 |
| 160 Similarly, there is an [Intl.gender][Intl.gender] message, and plurals | 167 Similarly, there is an [Intl.gender][Intl.gender] message, and plurals |
| 161 and genders can be nested. | 168 and genders can be nested. |
| 162 | 169 |
| 163 notOnlineMessage(String userName, String userGender) => | 170 notOnlineMessage(String userName, String userGender) => |
| 164 Intl.gender( | 171 Intl.gender( |
| 165 userGender, | 172 userGender, |
| 166 male: '$userName is unavailable because he is not online.', | 173 male: '$userName is unavailable because he is not online.', |
| 167 female: '$userName is unavailable because she is not online.', | 174 female: '$userName is unavailable because she is not online.', |
| 168 other: '$userName is unavailable because they are not online'), | 175 other: '$userName is unavailable because they are not online', |
| 169 name: "notOnlineMessage", | 176 name: "notOnlineMessage", |
| 170 args: [userName, userGender], | 177 args: [userName, userGender], |
| 171 desc: "The user is not available to hangout.", | 178 desc: "The user is not available to hangout.", |
| 172 examples: {{'userGender': 'male', 'userName': 'Fred'}, | 179 examples: const {{'userGender': 'male', 'userName': 'Fred'}, |
| 173 {'userGender': 'female', 'userName' : 'Alice'}}); | 180 {'userGender': 'female', 'userName' : 'Alice'}}); |
| 174 | 181 |
| 175 It's recommended to use complete sentences in the sub-messages to keep | 182 It's recommended to use complete sentences in the sub-messages to keep |
| 176 the structure as simple as possible for the translators. | 183 the structure as simple as possible for the translators. |
| 177 | 184 |
| 178 ## Extracting And Using Translated Messages | 185 ## Extracting And Using Translated Messages |
| 179 | 186 |
| 180 When your program contains messages that need translation, these must | 187 When your program contains messages that need translation, these must |
| 181 be extracted from the program source, sent to human translators, and the | 188 be extracted from the program source, sent to human translators, and the |
| 182 results need to be incorporated. | 189 results need to be incorporated. The code for this is in the |
| 190 [Intl_translation][Intl_translation] package. |
| 183 | 191 |
| 184 To extract messages, run the `extract_to_arb.dart` program. | 192 To extract messages, run the `extract_to_arb.dart` program. |
| 185 | 193 |
| 186 pub run intl:extract_to_arb --output-dir=target/directory | 194 pub run intl_translation:extract_to_arb --output-dir=target/directory |
| 187 my_program.dart more_of_my_program.dart | 195 my_program.dart more_of_my_program.dart |
| 188 | 196 |
| 189 This will produce a file `intl_messages.arb` with the messages from | 197 This will produce a file `intl_messages.arb` with the messages from |
| 190 all of these programs. an [ARB] | 198 all of these programs. an [ARB] |
| 191 (https://code.google.com/p/arb/wiki/ApplicationResourceBundleSpecification) | 199 (https://code.google.com/p/arb/wiki/ApplicationResourceBundleSpecification) |
| 192 format file which can be used for input to translation tools like | 200 format file which can be used for input to translation tools like |
| 193 [Google Translator Toolkit](https://translate.google.com/toolkit/) | 201 [Google Translator Toolkit](https://translate.google.com/toolkit/) |
| 194 The resulting translations can be used to generate a set of libraries | 202 The resulting translations can be used to generate a set of libraries |
| 195 using the `generate_from_arb.dart` program. | 203 using the `generate_from_arb.dart` program. |
| 196 | 204 |
| 197 This expects to receive a series of files, one per | 205 This expects to receive a series of files, one per |
| 198 locale. | 206 locale. |
| 199 | 207 |
| 200 pub run intl:generate_from_arb --generated_file_prefix=<prefix> | 208 ``` |
| 201 <my_dart_files> <translated_ARB_files> | 209 pub run intl_translation:generate_from_arb --generated_file_prefix=<prefix> |
| 210 <my_dart_files> <translated_ARB_files> |
| 211 ``` |
| 202 | 212 |
| 203 This will generate Dart libraries, one per locale, which contain the | 213 This will generate Dart libraries, one per locale, which contain the |
| 204 translated versions. Your Dart libraries can import the primary file, | 214 translated versions. Your Dart libraries can import the primary file, |
| 205 named `<prefix>messages_all.dart`, and then call the initialization | 215 named `<prefix>messages_all.dart`, and then call the initialization |
| 206 for a specific locale. Once that's done, any | 216 for a specific locale. Once that's done, any |
| 207 [Intl.message][Intl.message] calls made in the context of that locale | 217 [Intl.message][Intl.message] calls made in the context of that locale |
| 208 will automatically print the translated version instead of the | 218 will automatically print the translated version instead of the |
| 209 original. | 219 original. |
| 210 | 220 |
| 211 import "my_prefix_messages_all.dart"; | 221 import "my_prefix_messages_all.dart"; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 The class [BidiFormatter][BidiFormatter] provides utilities for | 310 The class [BidiFormatter][BidiFormatter] provides utilities for |
| 301 working with Bidirectional text. We can wrap the string with unicode | 311 working with Bidirectional text. We can wrap the string with unicode |
| 302 directional indicator characters or with an HTML span to indicate | 312 directional indicator characters or with an HTML span to indicate |
| 303 direction. The direction can be specified with the | 313 direction. The direction can be specified with the |
| 304 [RTL][BidiFormatter.RTL] and [LTR][BidiFormatter.LTR] constructors, or | 314 [RTL][BidiFormatter.RTL] and [LTR][BidiFormatter.LTR] constructors, or |
| 305 detected from the text. | 315 detected from the text. |
| 306 | 316 |
| 307 new BidiFormatter.RTL().wrapWithUnicode('xyz'); | 317 new BidiFormatter.RTL().wrapWithUnicode('xyz'); |
| 308 new BidiFormatter.RTL().wrapWithSpan('xyz'); | 318 new BidiFormatter.RTL().wrapWithSpan('xyz'); |
| 309 | 319 |
| 310 [intl_lib]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/intl
/intl | 320 [intl_lib]: https://www.dartdocs.org/documentation/intl/latest/intl/intl-library
.html |
| 311 [Intl]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/intl | 321 [Intl]: https://www.dartdocs.org/documentation/intl/latest |
| 312 [DateFormat]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/in
tl/intl.DateFormat | 322 [DateFormat]: https://www.dartdocs.org/documentation/intl/latest/intl/DateFormat
-class.html |
| 313 [NumberFormat]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/
intl/intl.NumberFormat | 323 [NumberFormat]: https://www.dartdocs.org/documentation/intl/latest/intl/NumberFo
rmat-class.html |
| 314 [withLocale]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/in
tl/intl.Intl#id_withLocale | 324 [withLocale]: https://www.dartdocs.org/documentation/intl/latest/intl/Intl/withL
ocale.html |
| 315 [defaultLocale]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer
/intl/intl.Intl#id_defaultLocale | 325 [defaultLocale]: https://www.dartdocs.org/documentation/intl/latest/intl/Intl/de
faultLocale.html |
| 316 [Intl.message]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/
intl/intl.Intl#id_message | 326 [Intl.message]: https://www.dartdocs.org/documentation/intl/latest/intl/Intl/mes
sage.html |
| 317 [Intl.plural]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/i
ntl/intl.Intl#id_plural | 327 [Intl.plural]: https://www.dartdocs.org/documentation/intl/latest/intl/Intl/plur
al.html |
| 318 [Intl.gender]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/i
ntl/intl.Intl#id_gender | 328 [Intl.gender]: https://www.dartdocs.org/documentation/intl/latest/intl/Intl/gend
er.html |
| 319 [DateTime]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart
:core.DateTime | 329 [DateTime]: https://api.dartlang.org/stable/dart-core/DateTime-class.html |
| 320 [BidiFormatter]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer
/intl/intl.BidiFormatter | 330 [BidiFormatter]: https://www.dartdocs.org/documentation/intl/latest/intl/BidiFor
matter-class.html |
| 321 [BidiFormatter.RTL]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-vi
ewer/intl/intl.BidiFormatter#id_BidiFormatter-RTL | 331 [BidiFormatter.RTL]: https://www.dartdocs.org/documentation/intl/latest/intl/Bid
iFormatter/BidiFormatter.RTL.html |
| 322 [BidiFormatter.LTR]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-vi
ewer/intl/intl.BidiFormatter#id_BidiFormatter-LTR | 332 [BidiFormatter.LTR]: https://www.dartdocs.org/documentation/intl/latest/intl/Bid
iFormatter/BidiFormatter.LTR.html |
| OLD | NEW |