OLD | NEW |
| (Empty) |
1 Intl | |
2 ==== | |
3 | |
4 This package provides internationalization and localization facilities, | |
5 including message translation, plurals and genders, date/number formatting | |
6 and parsing, and bidirectional text. | |
7 | |
8 ## General | |
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 | |
11 internationalization mechanisms. This library also defines the | |
12 [DateFormat][DateFormat], [NumberFormat][NumberFormat], and | |
13 [BidiFormatter][BidiFormatter] classes. | |
14 | |
15 ## Current locale | |
16 | |
17 The package has a single current locale, called [defaultLocale][defaultLocale]. | |
18 Operations will use that locale unless told to do otherwise. | |
19 | |
20 To set the global locale, you can explicitly set it, e.g. | |
21 | |
22 Intl.defaultLocale = 'pt_BR'; | |
23 | |
24 or get it from the browser by | |
25 | |
26 import "package:intl/intl_browser.dart"; | |
27 ... | |
28 findSystemLocale().then(runTheRestOfMyProgram); | |
29 | |
30 To temporarily override the current locale, pass the operation | |
31 to [withLocale][withLocale]. | |
32 | |
33 Intl.withLocale('fr', () => print(myLocalizedMessage()); | |
34 | |
35 To override it for a very specific operation you can create a format object in | |
36 a specific locale, or pass in the locale as a parameter to methods. | |
37 | |
38 var format = new DateFormat.yMd("ar"); | |
39 var dateString = format.format(new DateTime.now()); | |
40 print(myMessage(dateString, locale: 'ar'); | |
41 | |
42 ## Initialization | |
43 | |
44 All the different types of locale data require an async initialization step | |
45 to make | |
46 sure the data is available. This reduces the size of the application by only | |
47 loading the | |
48 data that is actually required. | |
49 | |
50 Each different area of internationalization (messages, dates, numbers) requires | |
51 a separate initialization process. That way, if the application only needs to | |
52 format dates, it doesn't need to take the time or space to load up messages, | |
53 numbers, or other things it may not need. | |
54 | |
55 With messages, there is also a need to import a file that won't exist until | |
56 the code generation step has been run. This can be awkward, but can be worked | |
57 around by creating a stub `messages_all.dart` file, running an empty translation | |
58 step, or commenting out the import until translations are available. | |
59 See "Extracting and Using Translated Messages" | |
60 | |
61 ## Messages | |
62 | |
63 Messages to be localized are written as functions that return the result of | |
64 an [Intl.message][Intl.message] call. | |
65 | |
66 String continueMessage() => Intl.message( | |
67 "Hit any key to continue", | |
68 name: "continueMessage", | |
69 args: [], | |
70 desc: "Explains that we will not proceed further until " | |
71 "the user presses a key"); | |
72 print(continueMessage()); | |
73 | |
74 This provides, in addition to the basic message string, a name, a | |
75 description for translators, the arguments used in the message, and | |
76 examples. The `name` and `args` parameters are required, and must | |
77 match the name and arguments list of the function. In the future we | |
78 hope to have these provided automatically. | |
79 | |
80 This can be run in the program before any translation has been done, | |
81 and will just return the message string. It can also be extracted to a | |
82 file and then be made to return a translated version without modifying | |
83 the original program. See "Extracting Messages" below for more | |
84 details. | |
85 | |
86 The purpose of wrapping the message in a function is to allow it to | |
87 have parameters which can be used in the result. The message string is | |
88 allowed to use a restricted form of Dart string interpolation, where | |
89 only the function's parameters can be used, and only in simple | |
90 expressions. Local variables cannot be used, and neither can | |
91 expressions with curly braces. Only the message string can have | |
92 interpolation. The name, desc, args, and examples must be literals and | |
93 not contain interpolations. Only the args parameter can refer to | |
94 variables, and it should list exactly the function parameters. If you | |
95 are passing numbers or dates and you want them formatted, you must do | |
96 the formatting outside the function and pass the formatted string into | |
97 the message. | |
98 | |
99 greetingMessage(name) => Intl.message( | |
100 "Hello $name!", | |
101 name: "greetingMessage", | |
102 args: [name], | |
103 desc: "Greet the user as they first open the application", | |
104 examples: {'name': "Emily"}); | |
105 print(greetingMessage('Dan')); | |
106 | |
107 There is one special class of complex expressions allowed in the | |
108 message string, for plurals and genders. | |
109 | |
110 remainingEmailsMessage(int howMany, String userName) => | |
111 Intl.message( | |
112 "${Intl.plural(howMany, | |
113 zero: 'There are no emails left for $userName.', | |
114 one: 'There is one email left for $userName.', | |
115 other: 'There are $howMany emails left for $userName.')}", | |
116 name: "remainingEmailsMessage", | |
117 args: [howMany, userName], | |
118 desc: "How many emails remain after archiving.", | |
119 examples: {'number': 42, 'userName': 'Fred'}); | |
120 | |
121 print(remainingEmailsMessage(1, "Fred")); | |
122 | |
123 However, since the typical usage for a plural or gender is for it to | |
124 be at the top-level, we can also omit the [Intl.message][Intl.message] call and | |
125 provide its parameters to the [Intl.plural][Intl.plural] call instead. | |
126 | |
127 remainingEmailsMessage(int howMany, String userName) => | |
128 Intl.plural( | |
129 howMany, | |
130 zero: 'There are no emails left for $userName.', | |
131 one: 'There is one email left for $userName.', | |
132 other: 'There are $howMany emails left for $userName.'), | |
133 name: "remainingEmailsMessage", | |
134 args: [howMany, userName], | |
135 desc: "How many emails remain after archiving.", | |
136 examples: {'number': 42, 'userName': 'Fred'}); | |
137 | |
138 Similarly, there is an [Intl.gender][Intl.gender] message, and plurals | |
139 and genders can be nested. | |
140 | |
141 notOnlineMessage(String userName, String userGender) => | |
142 Intl.gender( | |
143 userGender, | |
144 male: '$userName is unavailable because he is not online.', | |
145 female: '$userName is unavailable because she is not online.', | |
146 other: '$userName is unavailable because they are not online'), | |
147 name: "notOnlineMessage", | |
148 args: [userName, userGender], | |
149 desc: "The user is not available to hangout.", | |
150 examples: {{'userGender': 'male', 'userName': 'Fred'}, | |
151 {'userGender': 'female', 'userName' : 'Alice'}}); | |
152 | |
153 It's recommended to use complete sentences in the sub-messages to keep | |
154 the structure as simple as possible for the translators. | |
155 | |
156 ## Extracting And Using Translated Messages | |
157 | |
158 When your program contains messages that need translation, these must | |
159 be extracted from the program source, sent to human translators, and the | |
160 results need to be incorporated. | |
161 | |
162 To extract messages, run the `extract_to_arb.dart` program. | |
163 | |
164 pub run intl:extract_to_arb --output-dir=target/directory | |
165 my_program.dart more_of_my_program.dart | |
166 | |
167 This will produce a file `intl_messages.arb` with the messages from | |
168 all of these programs. an [ARB] | |
169 (https://code.google.com/p/arb/wiki/ApplicationResourceBundleSpecification) | |
170 format file which can be used for input to translation tools like | |
171 [Google Translator Toolkit](https://translate.google.com/toolkit/) | |
172 The resulting translations can be used to generate a set of libraries | |
173 using the `generate_from_arb.dart` program. | |
174 | |
175 This expects to receive a series of files, one per | |
176 locale. | |
177 | |
178 pub run intl:generate_from_arb --generated_file_prefix=<prefix> | |
179 <my_dart_files> <translated_ARB_files> | |
180 | |
181 This will generate Dart libraries, one per locale, which contain the | |
182 translated versions. Your Dart libraries can import the primary file, | |
183 named `<prefix>messages_all.dart`, and then call the initialization | |
184 for a specific locale. Once that's done, any | |
185 [Intl.message][Intl.message] calls made in the context of that locale | |
186 will automatically print the translated version instead of the | |
187 original. | |
188 | |
189 import "my_prefix_messages_all.dart"; | |
190 ... | |
191 initializeMessages("dk").then(printSomeMessages); | |
192 | |
193 Once the future returned from the initialization call returns, the | |
194 message data is available. | |
195 | |
196 ## Number Formatting and Parsing | |
197 | |
198 To format a number, create a NumberFormat instance. | |
199 | |
200 var f = new NumberFormat("###.0#", "en_US"); | |
201 print(f.format(12.345)); | |
202 ==> 12.34 | |
203 | |
204 The locale parameter is optional. If omitted, then it will use the | |
205 current locale. The format string is as described in | |
206 [NumberFormat][NumberFormat] | |
207 | |
208 It's also possible to access the number symbol data for the current | |
209 locale, which provides information as to the various separator | |
210 characters, patterns, and other information used for formatting, as | |
211 | |
212 f.symbols | |
213 | |
214 Current known limitations are that the currency format will only print | |
215 the name of the currency, and does not support currency symbols, and | |
216 that the scientific format does not really agree with scientific | |
217 notation. Number parsing is not yet implemented. | |
218 | |
219 Note that before doing any number formatting for a particular locale | |
220 you must load the appropriate data by calling | |
221 | |
222 import 'package:intl/number_symbols_data_local.dart'; | |
223 ... | |
224 initializeNumberFormatting(localeName, null).then(formatNumbers); | |
225 | |
226 Once the future returned from the initialization call returns, the | |
227 formatting data is available. Note that right now this includes all | |
228 the data for a locales. We expect to make this use deferred loading to | |
229 reduce code size. | |
230 | |
231 ## Date Formatting and Parsing | |
232 | |
233 To format a [DateTime][DateTime], create a [DateFormat][DateFormat] | |
234 instance. These can be created using a set of commonly used skeletons | |
235 taken from ICU/CLDR or using an explicit pattern. For details on the | |
236 supported skeletons and patterns see [DateFormat][DateFormat]. | |
237 | |
238 new DateFormat.yMMMMEEEEd().format(aDateTime); | |
239 ==> 'Wednesday, January 10, 2012' | |
240 new DateFormat("EEEEE", "en_US").format(aDateTime); | |
241 ==> 'Wednesday' | |
242 new DateFormat("EEEEE", "ln").format(aDateTime); | |
243 ==> 'mokɔlɔ mwa mísáto' | |
244 | |
245 You can also parse dates using the same skeletons or patterns. | |
246 | |
247 new DateFormat.yMd("en_US").parse("1/10/2012"); | |
248 new DateFormat("Hms", "en_US").parse('14:23:01'); | |
249 | |
250 Skeletons can be combined, the main use being to print a full date and | |
251 time, e.g. | |
252 | |
253 new DateFormat.yMEd().add_jms().format(new DateTime.now()); | |
254 ==> 'Thu, 5/23/2013 10:21:47 AM' | |
255 | |
256 Known limitations: Time zones are not yet supported. Dart | |
257 [DateTime][DateTime] objects don't have a time zone, so are either | |
258 local or UTC. Formatting and parsing Durations is not yet implemented. | |
259 | |
260 Note that before doing any DateTime formatting for a particular | |
261 locale, you must load the appropriate data by calling. | |
262 | |
263 import 'package:intl/date_symbol_data_local.dart'; | |
264 ... | |
265 initializeDateFormatting("de_DE", null).then(formatDates); | |
266 | |
267 Once the future returned from the initialization call returns, the | |
268 formatting data is available. | |
269 | |
270 There are other mechanisms for loading the date formatting data | |
271 implemented, but we expect to deprecate those in favor of having the | |
272 data in a library as in the above, and using deferred loading to only | |
273 load the portions that are needed. For the time being, this will | |
274 include all of the data, which will increase code size. | |
275 | |
276 ## Bidirectional Text | |
277 | |
278 The class [BidiFormatter][BidiFormatter] provides utilities for | |
279 working with Bidirectional text. We can wrap the string with unicode | |
280 directional indicator characters or with an HTML span to indicate | |
281 direction. The direction can be specified with the | |
282 [RTL][BidiFormatter.RTL] and [LTR][BidiFormatter.LTR] constructors, or | |
283 detected from the text. | |
284 | |
285 new BidiFormatter.RTL().wrapWithUnicode('xyz'); | |
286 new BidiFormatter.RTL().wrapWithSpan('xyz'); | |
287 | |
288 [intl_lib]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/intl
/intl | |
289 [Intl]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/intl | |
290 [DateFormat]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/in
tl/intl.DateFormat | |
291 [NumberFormat]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/
intl/intl.NumberFormat | |
292 [withLocale]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/in
tl/intl.Intl#id_withLocale | |
293 [defaultLocale]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer
/intl/intl.Intl#id_defaultLocale | |
294 [Intl.message]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/
intl/intl.Intl#id_message | |
295 [Intl.plural]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/i
ntl/intl.Intl#id_plural | |
296 [Intl.gender]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/i
ntl/intl.Intl#id_gender | |
297 [DateTime]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart
:core.DateTime | |
298 [BidiFormatter]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer
/intl/intl.BidiFormatter | |
299 [BidiFormatter.RTL]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-vi
ewer/intl/intl.BidiFormatter#id_BidiFormatter-RTL | |
300 [BidiFormatter.LTR]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-vi
ewer/intl/intl.BidiFormatter#id_BidiFormatter-LTR | |
OLD | NEW |