Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<com:TContent ID="body" >
2
 
3
<h1 id="6201">Internationalization (I18N) and Localization (L10N)</h1>
4
<p id="790625" class="block-content">Many web application built with PHP will not have internationalization in mind when it was first written. It may be that it was not intended for use in languages and cultures. Internationalization is an important aspect due to the increase adoption of the Internet in many non-English speaking countries. The process of internationalization and localization will contain difficulties. Below are some general guidelines to internationalize an existing application.</p>
5
 
6
<h2 id="6203">Separate culture/locale sensitive data</h2>
7
 
8
<p id="790626" class="block-content">Identify and separate data that varies with culture. The most obvious are text/string/message. Other type of data should also be considered. The following list categorize some examples of culture sensitive data
9
</p>
10
 
11
<ul id="u1" class="block-content">
12
    <li> Strings, Messages, Text, in relatively small units (e.g. phrases, sentences, paragraphs, but not the full text of a book).</li>
13
    <li> Labels on buttons.</li>
14
    <li> Help files, large units of text, static text.</li>
15
    <li> Sounds.</li>
16
    <li> Colors.</li>
17
    <li> Graphics,Icons.</li>
18
    <li> Dates, Times.</li>
19
    <li> Numbers, Currency, Measurements.</li>
20
    <li> Phone numbers.</li>
21
    <li> Honorific and personal titles.</li>
22
    <li> Postal address.</li>
23
    <li> Page layout.</li>
24
</ul>
25
 
26
<p id="790627" class="block-content">If possible all manner of text should be isolated and store in a persistence format. These text include, application error messages, hard coded strings in PHP files, emails, static HTML text, and text on form elements (e.g. buttons).</p>
27
 
28
<h2 id="6204">Configuration</h2>
29
<p id="790628" class="block-content">To enable the localization features in PRADO, you need to add a few configuration options in your <a href="?page=Configurations.AppConfig">application configuration</a>.
30
First you need to include the <tt>System.I18N.*</tt> namespace to your paths.
31
</p>
32
<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_790203">
33
<paths>
34
    <using namespace="System.I18N.*" />
35
</paths>
36
</com:TTextHighlighter>
37
 
38
<p id="790629" class="block-content">Then, if you wish to translate some text in your application, you need to add one translation message data source.</p>
39
<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_790204">
40
<module id="globalization" class="TGlobalization">
41
    <translation type="XLIFF"
42
        source="MyApp.messages"
43
        marker="@@"
44
        autosave="true" cache="true" />
45
</module>
46
</com:TTextHighlighter>
47
 
48
<p id="790630" class="block-content">Where <tt>source</tt> in <tt>translation</tt> is the dot path to a directory
49
where you are going to store your translate message catalogue. The <tt>autosave</tt>
50
attribute if enabled, saves untranslated messages back into the message catalogue.
51
With <tt>cache</tt> enabled, translated messages are saved in the application <tt>runtime/i18n</tt> directory.
52
The <tt>marker</tt> value is used to surround any untranslated text.
53
</p>
54
 
55
<p id="790631" class="block-content">With the configuration complete, we can now start to localize your application. If you have <tt>autosave</tt> enabled, after running your application with some localization activity (i.e. translating some text), you will see a directory and a <tt>messages.xml</tt> created within your <tt>source</tt> directory.</p>
56
 
57
<h2 id="6205">What to do with <tt>messages.xml</tt>?</h2>
58
<p id="790632" class="block-content">The translation message catalogue file, if using <tt>type="XLIFF"</tt>, is a standardized translation message interchange XML format. You can edit the XML file using any UTF-8 aware editor. The format of the XML is something like the following.</p>
59
 
60
<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_790205">
61
<?xml version="1.0"?>
62
<xliff version="1.0">
63
    <file original="I18N Example IndexPage"
64
          source-language="EN"
65
          datatype="plaintext"
66
          date="2005-01-24T11:07:53Z">
67
        <body>
68
 
69
<trans-unit id="1">
70
<source>Hello world.</source>
71
<target>Hi World!!!</target>
72
</trans-unit>
73
 
74
        </body>
75
    </file>
76
</xliff>
77
</com:TTextHighlighter>
78
 
79
Each translation message is wrapped within a <tt>trans-unit</tt> tag, where <tt>source</tt> is the original message, and <tt>target</tt> is the translated message. Editors such as <a href="http://www.heartsome.net/EN/xlfedit.html">Heartsome XLIFF Translation Editor</a> can help in editing these XML files.
80
 
81
<h2>Using a Database for translation</h2>
82
 
83
<com:SinceVersion Version="3.1.3" />
84
<p>Since version 3.1.3 the messages can also be stored in a database using the connection id from an existing <tt>TDataSourceConfig</tt>. You have to create two tables in your database: <tt>catalogue</tt> and <tt>trans_unit</tt>. The catalogue table needs an entry for each catalogue you want to use. Example schemas for different databases can be found in the framework's <tt>I18N/schema</tt> directory. To configure translation with a database use:</>
85
 
86
<com:TTextHighlighter Language="xml" CssClass="source block-content">
87
<module id="db1" class="System.Data.TDataSourceConfig">
88
    <database ConnectionString="mysql:host=localhost;dbname=demodb" Username="demo" Password="demo" />
89
</module>
90
 
91
<module id="globalization" class="TGlobalization">
92
    <translation
93
        type="Database"
94
        autosave="true"
95
        cache="false"
96
        source="db1" />
97
</module>
98
</com:TTextHighlighter>
99
 
100
<p>The translation messages will be stored in the <tt>trans_unit</tt> table. Add your translation in the <tt>target</tt> field of that table. You should make sure that you are working on the right catalogue by comparing the message's <tt>cat_id</tt> with that from the catalogue table.</p>
101
 
102
<h2 id="6206">Setting and Changing Culture</h2>
103
<p id="790633" class="block-content">Once globalization is enabled, you can access the globalization settings, such as, <tt>Culture</tt>, <tt>Charset</tt>, etc, using </p>
104
<com:TTextHighlighter CssClass="source block-content" id="code_790206">
105
$globalization = $this->getApplication()->getGlobalization();
106
echo $globalization->Culture;
107
$globalization->Charset= "GB-2312"; //change the charset
108
</com:TTextHighlighter>
109
 
110
<p id="790634" class="block-content">You also change the way the culture is determined by changing the <tt>class</tt> attribute in the module configuration. For example, to set the culture that depends on the browser settings, you can use the <tt>TGlobalizationAutoDetect</tt> class.
111
<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code_790207">
112
<module id="globalization" class="TGlobalizationAutoDetect">
113
   ...
114
</module>
115
</com:TTextHighlighter>
116
 
117
<p id="790635" class="block-content">You may also provide your own globalization class to change how the application culture is set.
118
Lastly, you can change the globalization settings on page by page basis using <a href="?page=Configurations.Templates1#tct">template control tags</a>. For example, changing the <tt>Culture</tt> to "zh".</p>
119
<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790208">
120
&lt;%@ Application.Globalization.Culture="zh" %&gt;
121
</com:TTextHighlighter>
122
 
123
<h2 id="6207">Localizing your PRADO application</h2>
124
There are two areas in your application that may need message or string localization, in PHP code and in the templates. To localize strings within PHP, use the <tt>localize</tt> function detailed below. To localize text in the template, use the <a href="#ttranslate">TTranslate</a> component.
125
<h2 id="6208">Using <tt>localize</tt> function to translate text within PHP</h2>
126
 
127
<p id="790636" class="block-content">The <tt>localize</tt> function searches for a translated string that matches original from your translation source. First, you need to locate all the hard coded text in PHP that are displayed or sent to the end user. The following example localizes the text of the <tt>$sender</tt> (assuming, say, the sender is a button). The original code before localization is as follows.
128
<com:TTextHighlighter CssClass="source block-content" id="code_790209">
129
function clickMe($sender,$param)
130
{
131
  $sender->Text="Hello, world!";
132
}
133
</com:TTextHighlighter>
134
 
135
<p id="790637" class="block-content">The hard coded message "Hello, world!" is to be localized using the <tt>localize</tt> function. </p>
136
<com:TTextHighlighter CssClass="source block-content" id="code_790210">
137
function clickMe($sender,$param)
138
{
139
  $sender->Text=Prado::localize("Hello, world!");
140
}
141
</com:TTextHighlighter>
142
 
143
<h2 id="6209">Compound Messages</h2>
144
 
145
<p id="790638" class="block-content">Compound messages can contain variable data. For example, in the message "There are 12 users online.", the integer 12 may change depending on some data in your application. This is difficult to translate because the position of the variable data may be difference for different languages. In addition, different languages have their own rules for plurals (if any) and/or quantifiers. The following example can not be easily translated, because the sentence structure is fixed by hard coding the variable data within message.</p>
146
<com:TTextHighlighter CssClass="source block-content" id="code_790211">
147
$num_users = 12;
148
$message = "There are " . $num_users . " users online.";
149
</com:TTextHighlighter>
150
 
151
This problem can be solved using the <tt>localize</tt> function with string substitution. For example, the <tt>$message</tt> string above can be constructed as follows.
152
<com:TTextHighlighter CssClass="source block-content" id="code_790212">
153
$num_users = 12;
154
$message = Prado::localize("There are {num_users} users online.", array('num_users'=>$num_users));
155
</com:TTextHighlighter>
156
<p id="790639" class="block-content">Where the second parameter in <tt>localize</tt> takes an associative array with the key as the substitution to find in the text and replaced it with the associated value.
157
The <tt>localize</tt> function does not solve the problem of localizing languages that have plural forms, the solution is to use <a href="#choice-format">TChoiceFormat</a>.</p>
158
 
159
<p id="790640" class="block-content">The following sample demonstrates the basics of localization in PRADO.</p>
160
<com:RunBar PagePath="Advanced.Samples.I18N.Home" />
161
 
162
<h1 id="6202">I18N Components</h1>
163
<a name="ttranslate"></a>
164
<h2 id="6210">TTranslate</h2>
165
<p id="790641" class="block-content">Messages and strings can be localized in PHP or in templates.
166
To translate a message or string in the template, use <tt>TTranslate</tt>.</p>
167
 
168
<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790213">
169
&lt;com:TTranslate&gt;Hello World&lt;/com:TTranslate&gt;
170
&lt;com:TTranslate Text="Goodbye" /&gt;
171
</com:TTextHighlighter>
172
 
173
<p id="790642" class="block-content"><tt>TTranslate</tt> can also perform string substitution.
174
The <tt>Parameters</tt> property can be use to add name values pairs for substitution. Substrings in the translation enclosed with "{" and "}" are consider as the
175
 parameter names during substitution lookup. The following example will substitute the substring "{time}" with the value of the parameter attribute "<tt>Parameters.time=&lt;%= time() %&gt;</tt>".
176
<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790214">
177
&lt;com:TTranslate Parameters.time=&lt;%= time() %&gt; &gt;
178
The time is {time}.
179
&lt;/com:TTranslate&gt;
180
</com:TTextHighlighter>
181
 
182
<p id="790643" class="block-content">A short for <tt>TTranslate</tt> is also provided using the following syntax.</p>
183
<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790215">
184
&lt;%[string]%&gt;
185
</com:TTextHighlighter>
186
<p id="790644" class="block-content">where string will be translated to different languages according to the end-user's language preference. This syntax can be used with attribute values as well.</p>
187
<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790216">
188
&lt;com:TLabel Text="&lt;%[ Hello World! ]%&gt;" /&gt;
189
</com:TTextHighlighter>
190
 
191
<h2 id="6211">TDateFormat</h2>
192
<p id="790645" class="block-content">Formatting localized date and time is straight forward.</p>
193
<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790217">
194
&lt;com:TDateFormat Value="12/01/2005" /&gt;
195
</com:TTextHighlighter>
196
 
197
<p id="790646" class="block-content">The <tt>Pattern</tt> property accepts 4 predefined localized date patterns and 4 predefined localized time patterns.</p>
198
<ul id="u2" class="block-content">
199
	<li><tt>fulldate</tt></li>
200
	<li><tt>longdate</tt></li>
201
	<li><tt>mediumdate</tt></li>
202
	<li><tt>shortdate</tt></li>
203
	<li><tt>fulltime</tt></li>
204
	<li><tt>longtime</tt></li>
205
	<li><tt>mediumtime</tt></li>
206
	<li><tt>shorttime</tt></li>
207
</ul>
208
<p id="p1" class="block-content">
209
The predefined can be used in any combination. If using a combined predefined pattern,
210
the first pattern must be the date, followed by a space, and lastly the time pattern.
211
For example, full date pattern with short time pattern. The actual ordering of the
212
date-time and the actual pattern will be determine automatically from locale data specified
213
by the <tt>Culture</tt> property.</p>
214
 
215
<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790218">
216
&lt;com:TDateFormat Pattern="fulldate shorttime" /&gt;
217
</com:TTextHighlighter>
218
 
219
<p id="790647" class="block-content">You can also specify a custom pattern using the following sub-patterns.
220
The date/time format is specified by means of a string time pattern. In this pattern, all ASCII letters are reserved as pattern letters, which are defined as the following:
221
<com:TTextHighlighter Language="text" CssClass="source block-content" id="code_790219">
222
 Symbol   Meaning                 Presentation        Example
223
 ------   -------                 ------------        -------
224
 G        era designator          (Text)              AD
225
 y        year                    (Number)            1996
226
 M        month in year           (Text &amp; Number)     July &amp; 07
227
 d        day in month            (Number)            10
228
 h        hour in am/pm (1~12)    (Number)            12
229
 H        hour in day (0~23)      (Number)            0
230
 m        minute in hour          (Number)            30
231
 s        second in minute        (Number)            55
232
 E        day of week             (Text)              Tuesday
233
 D        day in year             (Number)            189
234
 F        day of week in month    (Number)            2 (2nd Wed in July)
235
 w        week in year            (Number)            27
236
 W        week in month           (Number)            2
237
 a        am/pm marker            (Text)              PM
238
 k        hour in day (1~24)      (Number)            24
239
 K        hour in am/pm (0~11)    (Number)            0
240
 z        time zone               (Time)              Pacific Standard Time
241
 '        escape for text         (Delimiter)         'Date='
242
 ''       single quote            (Literal)           'o''clock'
243
</com:TTextHighlighter>
244
</p>
245
 
246
<p id="790648" class="block-content">The count of pattern letters determine the format.</p>
247
 
248
<p id="790649" class="block-content">(Text): 4 letters uses full form, less than 4, use short or abbreviated form
249
if it exists. (e.g., "EEEE" produces "Monday", "EEE" produces "Mon")</p>
250
 
251
<p id="790650" class="block-content">(Number): the minimum number of digits. Shorter numbers are zero-padded
252
 to this amount (e.g. if "m" produces "6", "mm" produces "06"). Year is
253
 handled specially; that is, if the count of 'y' is 2, the Year will be
254
 truncated to 2 digits. (e.g., if "yyyy" produces "1997", "yy" produces "97".)
255
 Unlike other fields, fractional seconds are padded on the right with zero.</p>
256
 
257
<p id="790651" class="block-content">(Text and Number): 3 or over, use text, otherwise use number. (e.g.,
258
"M" produces "1", "MM" produces "01", "MMM" produces "Jan", and "MMMM"
259
produces "January".)</p>
260
 
261
<p id="790652" class="block-content">Any characters in the pattern that are not in the ranges of ['a'..'z']
262
and ['A'..'Z'] will be treated as quoted text. For instance, characters
263
like ':', '.', ' ', and '@' will appear in the resulting time text
264
even they are not embraced within single quotes.</p>
265
 
266
<p id="790653" class="block-content">Examples using the US locale:
267
 
268
<com:TTextHighlighter Language="text" CssClass="source block-content" id="code_790220">
269
Format Pattern                         Result
270
--------------                         -------
271
"yyyy.MM.dd G 'at' HH:mm:ss"      -&gt;&gt;  1996.07.10 AD at 15:08:56
272
"EEE, MMM d, ''yy"                -&gt;&gt;  Wed, Jul 10, '96
273
"h:mm a"                          -&gt;&gt;  12:08 PM
274
"hh 'o''clock' a, z"              -&gt;&gt;  12 o'clock PM, Pacific Daylight Time
275
"K:mm a"                          -&gt;&gt;  0:00 PM
276
"yyyy.MMMM.dd G hh:mm a"          -&gt;&gt;  1996.July.10 AD 12:08 PM
277
</com:TTextHighlighter>
278
</p>
279
 
280
<p id="790654" class="block-content">If the <tt>Value</tt> property is not specified, the current date and time is used.</p>
281
 
282
<h2 id="6212">TNumberFormat</h2>
283
<p id="790655" class="block-content">PRADO's Internationalization framework provide localized currency formatting and number formatting. Please note that the <tt>TNumberFormat</tt> component provides formatting only, it does not perform current conversion or exchange.</p>
284
 
285
<p id="790656" class="block-content">Numbers can be formatted as currency, percentage, decimal or scientific
286
numbers by specifying the <tt>Type</tt> attribute. The valid types are:</p>
287
<ul id="u3" class="block-content">
288
	<li><tt>currency</tt></li>
289
	<li><tt>percentage</tt></li>
290
	<li><tt>decimal</tt></li>
291
	<li><tt>scientific</tt></li>
292
</ul>
293
 
294
<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790221">
295
&lt;com:TNumberFormat Type="currency" Value="100" /&gt;
296
</com:TTextHighlighter>
297
 
298
<p id="790657" class="block-content"><tt>Culture</tt> and <tt>Currency</tt> properties may be specified to format locale specific numbers. </p>
299
 
300
<p id="790658" class="block-content">If someone from US want to see sales figures from a store in
301
Germany (say using the EURO currency), formatted using the german
302
 currency, you would need to use the attribute <tt>Culture="de_DE"</tt> to get
303
the currency right, e.g. 100,00$. The decimal and grouping separator is
304
then also from the <tt>de_DE</tt> locale. This may lead to some confusion because
305
people from US uses the "," (comma) as thousand separator. Therefore a <tt>Currency</tt>
306
attribute is available, so that the output from the following example results in $100.00
307
<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790222">
308
&lt;com:TNumberFormat Type="currency"
309
          Culture="en_US" Currency="EUR" Value="100" /&gt;
310
</com:TTextHighlighter>
311
</p>
312
 
313
<p id="790659" class="block-content">The <tt>Pattern</tt> property determines the number of digits, thousand grouping
314
positions, the number of decimal points and the decimal position. The actual characters that
315
are used to represent the decimal points and thousand points are culture specific
316
and will change automatically according to the <tt>Culture</tt> property. The valid
317
<tt>Pattern</tt> characters are:</p>
318
<ul id="u6" class="block-content">
319
	<li><tt># (hash)</tt> - represents the optional digits</li>
320
	<li><tt>0 (zero)</tt> - represents the mandatory digits, zero left filled</li>
321
	<li><tt>. (full stop)</tt> - the position of the decimal point (only 1 decimal point is allowed)</li>
322
	<li><tt>, (comma)</tt> - thousand point separation (up to 2 commas are allowed)</li>
323
</ul>
324
<p id="p2" class="block-content">
325
For example, consider the <tt>Value="1234567.12345"</tt> and
326
with <tt>Culture="en_US"</tt> (which uses "," for thousand point separator and "." for decimal separators).
327
</p>
328
<com:TTextHighlighter Language="text" CssClass="source block-content" id="code_790223">
329
Pattern                      Output
330
-------                      ------
331
##,###.00               -&gt;&gt;  1,234,567.12
332
##,###.##               -&gt;&gt;  1,234,567.12345
333
##,##.0000              -&gt;&gt;  1,23,45,67.1235
334
##,###,##.0             -&gt;&gt;  12,345,67.1
335
000,000,000.0           -&gt;&gt;  001,234,567.1
336
</com:TTextHighlighter>
337
</p>
338
 
339
<h2 id="6213">TTranslateParameter</h2>
340
<p id="790660" class="block-content">Compound messages, i.e., string substitution, can be accomplished with <tt>TTranslateParameter</tt>.
341
In the following example, the strings "{greeting}" and "{name}" will be replace
342
with the values of "Hello" and "World", respectively.The substitution string must be enclose with "{" and "}". The parameters can be further translated by using <tt>TTranslate</tt>.
343
 
344
<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790224">
345
&lt;com:TTranslate&gt;
346
  {greeting} {name}!
347
  &lt;com:TTranslateParameter Key="name">World&lt;/com:TTranslateParameter&gt;
348
  &lt;com:TTranslateParameter Key="greeting">Hello&lt;/com:TTranslateParameter&gt;
349
&lt;/com:TTranslate&gt;
350
</com:TTextHighlighter>
351
 
352
 
353
<a name="choice-format"></a>
354
<h2 id="6214">TChoiceFormat</h2>
355
 
356
<p id="790661" class="block-content">Using the <tt>localize</tt> function or <tt>TTranslate</tt> component to translate messages does not inform the translator the cardinality of the data required to determine the correct plural structure to use. It only informs them that there is a variable data, the data could be anything. Thus, the translator will be unable to determine with respect to the substitution data the correct plural, language structure or phrase to use . E.g. in English, to translate the sentence, "There are {number} of apples.", the resulting translation should be different depending on the <tt>number</tt> of apples.</p>
357
 
358
<p id="790662" class="block-content">The <tt>TChoiceFormat</tt> component performs message/string choice translation. The following example demonstrated a simple 2 choice message translation.</p>
359
 
360
<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code_790225">
361
&lt;com:TChoiceFormat Value="1"/&gt;[1] One Apple. |[2] Two Apples&lt;/com:TChoiceFormat&gt;
362
</com:TTextHighlighter>
363
 
364
<p id="790663" class="block-content">In the above example, the <tt>Value</tt> "1" (one), thus the translated string
365
is "One Apple". If the <tt>Value</tt> was "2", then it will show "Two Apples".</p>
366
 
367
<p id="790664" class="block-content">The message/string choices are separated by the pipe "|" followed by a set notation of the form.</p>
368
<ul id="u7" class="block-content">
369
    <li><tt>[1,2]</tt> -- accepts values between 1 and 2, inclusive.</li>
370
    <li><tt>(1,2)</tt> -- accepts values between 1 and 2, excluding 1 and 2.</li>
371
    <li><tt>{1,2,3,4}</tt> -- only values defined in the set are accepted.</li>
372
    <li><tt>[-Inf,0)</tt> -- accepts value greater or equal to negative infinity
373
                        and strictly less than 0</li>
374
</ul>
375
 
376
<p id="790665" class="block-content">Any non-empty combinations of the delimiters of square and round brackets are acceptable.
377
The string chosen for display depends on the <tt>Value</tt> property. The <tt>Value</tt> is evaluated for each set until the <tt>Value</tt> is found to belong to a particular set.</p>
378
 
379
<com:SinceVersion Version="3.1.1" />
380
<pi class="block-content"> Since version 3.1.1 the following set notation is also possible.</p>
381
<ul class="block-content">
382
    <li> <tt>{n: n % 10 > 1 && n % 10 < 5}</tt> --  matches numbers like 2, 3, 4, 22, 23, 24</li>
383
</ul>
384
 
385
<p class="block-content">Where set is defined by the expression after <tt>n:</tt>. In particular, the expression
386
accepts the following mathematical/logical operators to form a set of logical conditions
387
on the value given by <tt>n</tt>:</p>
388
<ul class="block-content">
389
    <li><tt>&lt;</tt> -- less than.</li>
390
    <li><tt>&lt;=</tt> -- less than equals.</li>
391
    <li><tt>&gt;</tt> -- greater than.</li>
392
    <li><tt>&gt=</tt> -- greater than equals.</li>
393
    <li><tt>==</tt> -- of equal value.</li>
394
    <li><tt>%</tt> -- modulo, e.g., 1 % 10 equals 1, 11 % 10 equals 1.</li>
395
    <li><tt>-</tt> -- minus, negative.</li>
396
    <li><tt>+</tt> -- addition.</li>
397
    <li><tt>&amp;</tt> -- conditional AND.</li>
398
    <li><tt>&amp;&amp;</tt> -- condition AND with short circuit.</li>
399
    <li><tt>|</tt> -- conditional OR.</li>
400
    <li><tt>||</tt> -- conditional OR with short circuit. </li>
401
    <li><tt>!</tt> -- negation.</li>
402
</ul>
403
<p class="block-content">Additional round brackets can also be used to perform grouping. The following example
404
represents ordinal values in English such as: "0th", "1st", "2nd", "3rd", "4th", "11th", "21st", "22nd", etc.</p>
405
 
406
<com:TTextHighlighter Language="prado" CssClass="source block-content" >
407
&lt;com:TChoiceFormat Value="21"&gt;
408
 {n: n > 0 && n % 10 == 1 && n % 100 != 11} {Value}st
409
|{n: n > 0 && n % 10 == 2 && n % 100 != 12} {Value}nd
410
|{n: n > 0 && n % 10 == 3 && n % 100 != 13} {Value}rd
411
|{n: n > -1 } {Value}th
412
|(-Inf, 0) {Value}
413
&lt;/com:TChoiceFormat&gt;
414
</com:TTextHighlighter>
415
 
416
 
417
 
418
<div class="last-modified">$Id: I18N.page 2472 2008-07-01 15:14:40Z mikl $</div></com:TContent>