lmarkus / Kraken_Example_Date_Format_Helper

A simple application that shows how to write and use a custom dustjs helper for date formatting
8 stars 4 forks source link

Kraken_Example_Date_Format_Helper

Formatting dates in JavaScript is usually an annoying task, but when you have to add in support for internationalization it becomes downright aggravating.

If your Kraken application needs to display dates, you can take advantage of dustjs-linkedin's helpers to let the template handle the formatting for you. This helps you keep your code concise, and separate the logic and interface layers cleanly.

In this example we'll create a helper that will format and localize a Date object for us.

The end goal is to create a helper in the form:

{@formatDate date="<date_object>" format="<format_string>"}

Where:

Example format_strings:

"dddd, MMMM Do YYYY, h:mm:ss a" => "Sunday, February 14th 2010, 3:25:50 pm"
"ddd, hA"                       => "Sun, 3PM"

This repository was created specifically to hold the example. If you look at the commit list, you will see how the application was built, step by step.

Starting point

This application picks up at the end of the KrakenJS Localization Example. You should follow that tutorial first to make sure that your application can handle different locales.

View commit

Dependencies

The first step is installing the excellent Moment.js library. This library implements date formatting and internationalization, so instead of reinventing the wheel, we'll take advantage of its great features.

npm install --save moment

View commit

Creating the helper as a library

Let's create ./lib/helper-dateFormat to hold our special helper.

Here's the relevant part of the helper code. It has been written following dustjs-linkedin's advice.

    //Create a helper called 'formatDate'
    dust.helpers.formatDate = function (chunk, context, bodies, params) {

        //Retrieve the date value from the template parameters.
        var date = dust.helpers.tap(params.date, chunk, context);

        //Retrieve the format string from the template parameters.
        var format = dust.helpers.tap(params.format, chunk, context);

        //Parse the date object using MomentJS
        var m = moment(new Date(date));

        //Format the string
        var output = m.format(format);

        //Write the final value out to the template
        return chunk.write(output);
    };

View commit

The helper library in action

To load the library, we'll require it from our applications entry point. In ./index.js:

//Load our custom helper
require('./lib/helper-formatDate');

Next, we'll add a date to the model to be rendered. In ./controllers/index.js:

model.theDate = new Date();
res.render('index', model);

Finally, we'll add our helper tag in the template to be rendered. In ./public/templates/index.js:

    <h2>Raw: {theDate}</h2>
    <h2>Formatted: {@formatDate date="{theDate}" format="dddd MMM Do YY"/}</h2>

We'll show both the raw and the formatted date for comparison.

View commit

Go ahead and give the application a spin and visit http://localhost:8000

$npm start

What about the localization?

Glad you asked. Since MomentJS supports localization out of the box, we simply need to feed a country-language pair that our application is currently set to. The Kraken Localization example that served as the starting point, switches randomly between three different languages.

The language becomes part of the context to be rendered, so we only need to make our helper aware of it:

In ./lib/helper-formatDate:

First we're going to load the project configuration. This will be used to retrieve the fallback language, as specified in ./config/app.json:

// Load the project's configuration
var nconf = require('nconf');

...

//Retrieve the fallback language from the configuration
var fallbackLang = nconf.get('i18n').fallback || 'en-US';

Next, we're going to dig the locality out of the context object:

//Dig the current language out of the context, or go to the fallback.
var lang = (context.stack && context.stack.head && context.stack.head.context && context.stack.head.context.locality) || fallbackLang;

Finally, we're going to provide the locality to the MomentJs object that will format the date:

//Set the language in which the date should be formatted
m.lang(lang);

And that's it.

Reload the page a few times, and as the locality changes randomly, the date will be formatted accordingly.

View commit

And you're done!

This is your example. If you find any typos, errors, bugs or you have suggestions for improvement, please feel free to open an issue, or send your pull requests.

Notes