Dust Intl Dust logo

Dust helpers for internationalization.

npm install dust-intl

This library provides a set of helpers to internationalize your Dust templates:

Features

Helpers

How It Works

Create a Dust Template Using a Helper

<p>{@formatNumber val=price style="currency" currency="USD"/}</p>

Render the Template

var context = {
    intl: {
        locales: 'en-US'
    },
    price: 1000
};

dust.renderSource(template, context, function(error, html) {
    // Rendered html available here.
});

Rendered

$1,000.00

Usage

Browser

1. Load the Scripts onto the Page

First, load Dust and Dust Intl onto the page:

<script src="dustjs-linkedin/dist/dust-full.min.js"></script>
<script src="dust-intl/dist/dust-intl.min.js"></script>

By default, dust-intl ships with the locale data for English built-in to the library's runtime. When you need to format data in another locale, include its data; e.g., for French:

<script src="dust-intl/dist/locale-data/fr.js"></script>

All 150+ languages supported by this library use their root BCP 47 language tag; i.e., the part before the first hyphen (if any).

Note: Older browsers do not have the built-in Intl APIs (ECMA-402). Read more on how to patch the browser runtime using a polyfill.

2. Register the Helpers

DustIntl.registerWith(dust);

Node/CommonJS

1. Require the Module

var dust     = require('dustjs-linkedin');
var DustIntl = require('dust-intl');

In Node.js, the data for all 150+ languages is pre-loaded and does not need to be loaded manually.

Note: Node.js <= 0.10 doesn't have the built-in Intl APIs (ECMA-402). Node.js 0.12 does, but the default build/distribution only supports English. Read more on how to patch Node.js using a polyfill.

2. Register the Helpers

DustIntl.registerWith(dust);

Format Numbers with Separators

The {@formatNumber} helper is used to represent a number in a way appropriate for the current locale. It formats numbers using Intl.NumberFormat and returns the formatted string value.

<ul>
    <li>{@formatNumber val=num/}</li>
    <li>{@formatNumber val=completed style="percent"/}</li>
    <li>{@formatNumber val=price style="currency" currency="USD"/}</li>
</ul>

Rendered

  • 42 000
  • 90 %
  • 100,95 US$

Using Named Number Formats

Specifying formatting options (e.g.: style="currency" currency="USD") in every call to {@formatNumber} in your templates can become a problem in large code bases, and isn't DRY. Instead, you can use context.intl.formats.number to define named number formats.

<ul>
    <li>{@formatNumber val=num/}</li>
    <li>{@formatNumber val=completed formatName="percentage"/}</li>
    <li>{@formatNumber val=price formatName="USD"/}</li>
</ul>

Rendered

  • 42 000
  • 90 %
  • 100,95 US$

In the example above, formatName="USD" and formatName="percentage" references the names of number formats defined in context.intl.formats.number, which is used when rendering the template. Check the RENDER tab to see the details.

See the custom formats section for more information.

Format Dates and Times Correctly

The {@formatDate} helper is used to represent a date in a way appropriate for the current locale. It formats dates using Intl.DateTimeFormat and returns the formatted string value.

<p>{@formatDate val=date month="long" day="numeric" year="numeric"/}</p>

Rendered

21. srpna. 2017

Specifying format options (e.g.: day="numeric" month="long" year="numeric") in every call to {@formatDate} in your templates can become a problem in large code bases, and isn't DRY. Instead, you can use context.intl.formats.date to define named date formats.

<p>{@formatDate val=date formatName="short"/}</p>

Rendered

21. srpna. 2017

In the example above, formatName="short" references the name of a date format defined in context.intl.formats.date. Check the RENDER tab to see the details.

See the custom formats section for more information.

Using Named Time Formats

The {@formatTime} is just like the {@formatDate} helper, except it will reference any named formats from context.intl.formats.time.

Format Dates Relative To "now"

The {@formatRelative} helper is used to represent a relative time in a way appropriate for the current locale. It formats the relative time following the rules from Unicode CLDR and returns the formatted string value.

<ul>
    <li>{@formatRelative val=postDate/}</li>
    <li>{@formatRelative val=commentDate/}</li>
    <li>{@formatRelative val=meetingDate/}</li>
</ul>

Rendered

  • včera
  • před 2 hodinami
  • za 1 hodinu

Using Specific Relative Units

By default, the relative time is formatted using the best fit unit of time. However, you can explicitly set the units option one of the following values:
"second", "minute", "hour", "day", "month" or "year".

<p>
    <b>{@formatRelative val=postDate/}</b> <i>(best fit)</i><br>
    <b>{@formatRelative val=postDate units="minute"/}</b> <i>(in minutes)</i>
</p>
<p>
    <b>{@formatRelative val=lastTrip/}</b> <i>(best fit)</i><br>
    <b>{@formatRelative val=lastTrip units="day"/}</b> <i>(in days)</i>
</p>

Rendered

včera (best fit)
před 1 320 minutami (in minutes)

před 2 měsíci (best fit)
před 70 dny (in days)

Using Specific Relative Styles

The style option provides another level of customization. By default, the relative time is computed with a "best fit" style, which means, for example, that instead of "1 day ago", it will display "yesterday", or "in 1 year" will be "next year", etc. The other style is "numeric", in which the output will always contain a number.

<p>
    <b>{@formatRelative val=postDate/}</b> <i>(best fit)</i><br>
    <b>{@formatRelative val=postDate style="numeric"/}</b> <i>(numeric)</i>
</p>
<p>
    <b>{@formatRelative val=lastTrip/}</b> <i>(best fit)</i><br>
    <b>{@formatRelative val=lastTrip style="numeric"/}</b> <i>(numeric)</i>
</p>

Rendered

včera (best fit)
před 1 dnem (numeric)

minulý rok (best fit)
před 1 rokem (numeric)

Using Named Relative Formats

Specifying format options (e.g.: style="numeric") in every call to {@formatRelative} in your templates can become a problem in large code bases, and isn't DRY. Instead, you can use context.intl.formats.relative to define named relative formats.

<p>
    <b>{@formatRelative val=postDate/}</b> <i>(best fit)</i><br>
    <b>{@formatRelative val=postDate formatName="hours"/}</b> <i>(hours, numeric)</i>
</p>
<p>
    <b>{@formatRelative val=lastTrip/}</b> <i>(best fit)</i><br>
    <b>{@formatRelative val=lastTrip formatName="hours"/}</b> <i>(hours, numeric)</i>
</p>

Rendered

včera (best fit)
před 24 hodinami (hours, numeric)

předevčírem (best fit)
před 48 hodinami (hours, numeric)

In the example above, formatName="hours" references the name of a relative format defined in context.intl.formats.relative. Check the RENDER tab to see the details.

See the custom formats section for more information.

Format Labels in the Template

When internationalizing Dust templates, you will need a way to localize your UI strings, including any logic pieces like pluralization rules for all the languages you wish to support. These strings should be externalized from your Dust templates so that the same template can be used for all languages.

The {@formatMessage} helper formats a translated message written in the ICU Message syntax, which is used by professional translators. The message format supports placeholders, plus choosing different strings based on pluralization, gender, or other criteria.

See the Guide for details on how to write those messages using the ICU Message syntax.

<p>
    {@formatMessage _key="photos"
        name=name
        numPhotos=numPhotos
        takenDate=takenDate/}
</p>

Rendered

21. srpna. 2017 Annie vyfotila 1 000 fotek.

In the example above, _key is used to lookup the localized string message by path from context.intl.messages that is passed into the template. Check the RENDER tab to see the details.

Additionally, you can leverage custom formats as described below, to specify a set of named format options to use in your messages, e.g: {someNum, number, USD} and {someDate, date, short} or {someTime, time, long}.

Create Intl Lambda

The {@intl} block helper can be used to create a new intl data scope by updating the intl context data supplied to Dust within the block. This is useful when you need to render part of the page in a particular locale.

<p>
    <b>{@formatDate val=date day="numeric" month="long"/}</b>
    <i> (current locale)</i>
</p>

{@intl locales="fr-FR"}
    <p>
        <b>{@formatDate val=date day="numeric" month="long"/}</b>
        <i> ("fr-FR" locale)</i>
    </p>
{/intl}

Rendered

21. srpna (current locale)

21 août ("fr-FR" locale)

You can use this approach for formats and messages, which are normally passed via context.intl object when rendering the template. Check the RENDER tab to see the details.

Define Your Own Custom Formats

Dust Intl allows you to define named formats that you can be used throughout your entire application or within a template and its partials. These named formats can be specified for date, time, number and relative format types. The following example illustrates how these custom named formats work.

<ul>
    <li>{@formatNumber   val=price     formatName="USD"/}</li>
    <li>{@formatDate     val=timestamp formatName="short"/}</li>
    <li>{@formatTime     val=now       formatName="hhmm"/}</li>
    <li>{@formatRelative val=yesterday formatName="hours"/}</li>
</ul>

Rendered

  • 1 400,34 US$
  • 23. ledna. 2014
  • 2:40
  • před 24 hodinami

In the example above, formatName="USD", formatName="short", formatName="hhmm", and formatName="hours" all reference the named custom formats defined in context.intl.formats. Check the RENDER tab to see the details.

Note: You can provide the context.intl.formats object when rendering the top-level template, and context.intl.formats will be propagated to any partial or helper.