UNPKG

zpt

Version:

Zenon Page Templates - JS (ZPT-JS)

292 lines (267 loc) 16.3 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>I18n</title> <script type="module" src="../js/zpt.js"></script> <script type="text/javascript" src="../lib/syntaxHighlighter/lib.js"></script> <link rel="stylesheet" type="text/css" href="../docs.css"> <link rel="stylesheet" type="text/css" href="../lib/syntaxHighlighter/theme.css"> </head> <body> <div data-use-macro="'page@templates.html'"> <div data-fill-slot="'page-header'"> <h1>ZPT-JS tutorial - I18n</h1> <ul> <li><a href="#intro">Intro to i18n</a>.</li> <li><a href="#examples">Some examples</a>.</li> <li><a href="#domains">Working with domains</a>.</li> <li><a href="#json">Loading messages from JSON files</a>.</li> <li><a href="#numbers">Numbers</a>.</li> <li><a href="#currencies">Currencies</a>.</li> <li><a href="#datesAndTimes">Dates and times</a>.</li> </ul> </div> <article data-fill-slot="'article'"> <h2 data-attributes="id 'intro'">Intro to i18n</h2> <p> Nowadays ZPT-JS has some i18n capabilities. How do they work? Let's see an example: </p> <strong>i18n.js</strong> <pre class="brush: js"> import { zpt } from './zpt-esm.js'; var I18n = zpt.I18n; var I18nBundle = zpt.I18nBundle; /* I18n maps init */ var msg = { en : {}, es : {} }; /* English i18n messages */ msg.en[ '/CONF/' ] = { language: 'en', locale: 'en-US' }; msg.en[ 'Hello world!' ] = 'Hello world!'; msg.en[ 'Results msg' ] = '{GENDER, select, male{He} female{She} other{They} }' + ' found ' + '{RES, plural, =0{no results} one{1 result} other{# results} }'; /* Spanish i18n messages */ msg.es[ '/CONF/' ] = { language: 'es', locale: 'es-ES' }; msg.es[ 'Hello world!' ] = '¡Hola mundo!'; msg.es[ 'Results msg' ] = '{ GENDER, select, male{Él} female{Ella} other{Ellos} }' + ' ' + '{ RES, plural, =0{no } other{} }' + '{ GENDER, select, male{ha} female{ha} other{han} }' + ' encontrado ' + '{ RES, plural, =0{ningún resultado} one{un único resultado} other{# resultados} }'; // Create I18n and i18nBundle instances var i18nES = new I18n( 'es', msg[ 'es' ] ); var i18nEN = new I18n( 'en', msg[ 'en' ] ); var i18nBundle = new I18nBundle( i18nES, i18nEN ); // Init dictionary var dictionary = { 'i18nBundle': i18nBundle }; // Parse template zpt.run({ root: document.body, dictionary: dictionary }); </pre> <strong>i18n.html</strong> <pre class="brush: html"> &lt;!DOCTYPE html&gt; &lt;html lang="es"&gt; &lt;head&gt; &lt;meta charset="utf-8"&gt; &lt;title&gt;Some I18n examples&lt;/title&gt; &lt;script src="i18n.js"&gt;&lt;/script&gt; &lt;/head&gt; &lt;body&gt; &lt;h1&gt;Some I18n expressions&lt;/h1&gt; &lt;ol data-language="'en'" data-domain="i18nBundle"&gt; &lt;li&gt; ¡Hola mundo! = &lt;span data-content="tr: 'Hello world!'"&gt;Must be ¡Hola mundo!&lt;/span&gt; &lt;/li&gt; &lt;li&gt; Él ha encontrado 10 resultados = &lt;span data-content="tr: 'Results msg' ( GENDER 'male'; RES 10 )"&gt;Must be 'Él ha encontrado 10 resultados'&lt;/span&gt; &lt;/li&gt; &lt;/ol&gt; &lt;/body&gt; &lt;/html&gt; </pre> <p> Some remarks about this: </p> <ul> <li>The dictionary must contain a source of i18n resources. ZPT-JS supports these types: <ul> <li>An instance of <code>I18n</code> class. Each instance includes all i18n strings in an i18n file in JSON format. The constructor of <code>I18n</code> class accepts 2 arguments; the first is the language of the messages and the second is a map (keys are the id of the messages and values the message themselves). The format of the messages must complain <a href="http://userguide.icu-project.org/formatparse/messages">ICU standards</a>.</li> <li>An array of instances of <code>I18n</code> classes.</li> <li>An instance of <code>I18nBundle</code> class. An instance of this class groups an instance of <code>I18n</code> class per supported language. They are useful to support using several languages in a template.</li> </ul> </li> <li>The <code>data-domain</code> attribute defines the source of i18n resources to use. It can be one or several instances of <code>I18n</code> or <code>I18nBundle</code> classes or an array of them.</li> <li>The <code>data-language</code> attribute defines the current language to use. It is needed when <code>data-domain</code> contains a <code>I18nBundle</code> instance, it is useless when we use <code>I18n</code> instances.</li> <li>The <code>tr</code> expression evaluates an expression but then it searches that value into the messages.</li> <li>The expression <code>'Hello world!'</code> is a literal, but <code>'Results msg' ( GENDER 'male'; RES 10 )</code> is a little more complex: <ol> <li>The first item is the message id: <code>'Results msg'</code>.</li> <li>The rest are variables used to build the message: <code>GENDER 'male'</code> defines a <code>GENDER</code> variable with <code>'male'</code> as value.</li> <li><code>RES 10</code> defines a <code>RES</code> variable with <code>10</code> as value.</li> </ol> </li> </ul> <h2 data-attributes="id 'examples'">Some examples</h2> <p> Some examples of i18n tags in action: </p> <ul> <li> <code>&lt;img src="image.png" data-attributes="title tr: 'Hello world!'"&gt;</code> adds an i18n title to the image. </li> <li> <code>&lt;li data-define="msg tr: 'Hello world!'"&gt;</code> defines a <code>msg</code> variable with the i18n message of <code>'Hello world!'</code>. </li> <li> <code>&lt;body data-on-error="tr: 'Oh, noooo!'"&gt;</code> sets the i18n message of <code>'Oh, noooo!'</code> as the message to show if an error occurs. </li> <li><code>&lt;span data-replace="tr: 'Hello world!'"&gt;</code> replaces the <code>span</code> tag by the i18n message of <code>'Hello world!'</code>.</li> </ul> <p> Some examples of valid <code>data-domain</code> attributes: </p> <ul> <li><code>data-domain="i18nES1"</code> Defines an instance of <code>I18n</code> class as the source of i18n strings.</li> <li><code>data-domain="i18nES2 i18nES1"</code> Defines 2 instances of <code>I18n</code> class as the source of i18n strings. ZPT will use the <em>i18nES2</em> instance first; if the string is not found will be use <em>i18nES1</em> instance.</li> <li><code>data-domain="i18nBundle1"</code> Defines an instance of <code>I18nBundle</code> class as the source of i18n strings.</li> <li><code>data-domain="i18nBundle2 i18nBundle1"</code>Defines 2 instances of <code>I18nBundle</code> class as the source of i18n strings.</li> <li><code>data-domain="i18nESArray"</code> Defines an array of instances of <code>I18n</code> class as the source of i18n strings. ZPT will use the first instance in the array; if the string is not found will be use the next instance until it is found.</li> </ul> <h2 data-attributes="id 'domains'">Working with domains</h2> <p> In the previous example the domain was a simple <code>I18nBundle</code> instance. This forces to use big maps with all the messages of one language. This can be awful if the amount of messages is big. <code>data-domain</code> tag supports also a list of <code>I18nBundle</code> instances, so the messages will be searched in the same order. </p> <p> Therefore, <code>data-domain="i18nBundle1 i18nBundle2"</code> allows to organise your i18n messages in 2 maps. The first one can contain general messages and the second one more particular messages (for example). </p> <p> <code>data-domain</code> also supports nested definitions: </p> <pre class="brush: html"> &lt;div data-domain="i18nBundle1"&gt; &lt;span data-content="tr: 'Hello world!'"&gt; ¡Hola mundo! &lt;/span&gt; &lt;span data-domain="i18nBundle2" data-content="tr: 'Hello world!'"&gt; ¡¡¡Hola mundo 2!!! &lt;/span&gt; &lt;/div&gt; </pre> <p> The first <code>data-content</code> will search only in <code>i18nBundle1</code>. The second one will search first in <code>i18nBundle2</code> and if it is not found will search in <code>i18nBundle1</code>. </p> <h2 data-attributes="id 'json'">Loading messages from JSON files</h2> <p> ZPT-JS makes it easy loading i18n messages from JSON files: </p> <pre class="brush: js"> zpt.run({ command: 'preload', root: document.body, dictionary: dictionary, i18n: { urlPrefix: './i18n/', files: { 'es': [ 'es1.json', 'es2.json' ], 'en': [ 'en1.json', 'en2.json' ] } }, callback: function(){ // Add I18nBundle instances to dictionary dictionary.i18nBundle1 = new I18nBundle( dictionary.i18nES1, dictionary.i18nEN1 ); dictionary.i18nBundle2 = new I18nBundle( dictionary.i18nES2, dictionary.i18nEN2 ); // Run ZPT zpt.run(); } }); </pre> <p> ZPT will add to dictionary these vars: </p> <ul> <li><em>i18nES1</em>. Includes all texts from <em>es1.json</em> file.</li> <li><em>i18nES2</em>. Includes all texts from <em>es2.json</em> file.</li> <li><em>i18nEN1</em>. Includes all texts from <em>en1.json</em> file.</li> <li><em>i18nEN2</em>. Includes all texts from <em>en2.json</em> file.</li> <li><em>i18nESArray</em>. An array with all spanish texts, in this example <em>[ i18nES2, i18nES1 ]</em>.</li> <li><em>i18nENArray</em>. An array with all english texts, in this example <em>[ i18nEN2, i18nEN1 ]</em>.</li> <li><em>i18nArray</em>. An array with all texts defined only if only one language is present. In this example it would not be defined, there are 2 languages.</li> </ul> <p> The order in arrays is inverted: first the last files, then the first. </p> <p> The bundles (<em>i18nBundle1</em> and <em>i18nBundle2</em>) are not required, add to the dictionary if you need them. </p> <h2 data-attributes="id 'numbers'">Numbers</h2> <p> ZPT-JS uses <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Intl">Intl</a> as i18n API for numbers. Let's see some examples: </p> <ul> <li> <code>&lt;span data-content="trNumber: 1355.23"&gt;</code> formats that number depending on the active i18n domain (<em>1,355.23</em> in english, <em>1.355,23</em> in spanish...). </li> <li> <code>&lt;span data-content="trNumber: 1355.23643 ( maximumFractionDigits 3 )"&gt;</code> formats that number depending on the active i18n domain and using a maximum of 3 fraction digits (<em>1,355.236</em> in english, <em>1.355,236</em> in spanish...). </li> <li> <code>&lt;span data-content="trNumber: 1355.23643 ( maximumFractionDigits 3; minimumIntegerDigits 6 )"&gt;</code> formats that number depending on the active i18n domain and using a maximum of 3 fraction digits and a minimum of 6 integer digits (<em>001,355.236</em> in english, <em>001.355,236</em> in spanish...). </li> </ul> <p> Take a look on <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat">NumberFormat options</a> to see all available options. </p> <h2 data-attributes="id 'currencies'">Currencies</h2> <p> ZPT-JS uses <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Intl">Intl</a> as i18n API for currencies. Let's see some examples: </p> <ul> <li> <code>&lt;span data-content="trCurrency: 'EUR' 1355.23"&gt;</code> formats that number depending on the active i18n domain and using that currency (<em>€ 1,355.23</em> in english, <em>1.355,23 €</em> in spanish...). </li> <li> <code>&lt;span data-content="trCurrency: 'USD' 1355.23 ( currencyDisplay 'name' )"&gt;</code> uses the name of the currency (<em>1,355.23 US dollars</em> in english, <em>1.355,23 € dólares estadounidenses</em> in spanish...). </li> </ul> <p> Options are the same as numbers (<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat">NumberFormat options</a>) plus some specific options of currencies. </p> <h2 data-attributes="id 'datesAndTimes'">Dates and times</h2> <p> ZPT-JS uses <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Intl">Intl</a> as i18n API for date and times. Let's see some examples: </p> <ul> <li> <code>&lt;span data-content="trDate: ( js: new Date( Date.UTC( 2012, 11, 21, 3, 0, 0 ) ) )"&gt;</code> formats that date depending on the active i18n domain (<em>12/21/2012</em> in english, <em>21/12/2012</em> in spanish...). </li> <li> <code>&lt;span data-content="trDate: ( js: new Date( Date.UTC( 2012, 11, 21, 3, 0, 0 ) ) ) ( weekday 'long'; year 'numeric'; month 'long'; day 'numeric' )"&gt;</code> formats that date with some options (<em>Friday, December 21, 2012</em> in english, <em>viernes, 21 de diciembre de 2012</em> in spanish...). </li> <li> <code>&lt;span data-content="trDate: ( js: new Date( Date.UTC( 2012, 11, 21, 3, 0, 0 ) ) ) ( hour 'numeric'; minute 'numeric'; second 'numeric' )"&gt;</code> formats that date with some options (<em>4:00:00 AM</em> in english, <em>4:00:00</em> in spanish...). </li> </ul> <p> Take a look on <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat">DateTimeFormat options</a> to see all available options. </p> </article> </div> </body> </html>