i18n with polyglot.js and rendr.js
var patches = require('./lib/patches') | |
, BaseApp = require('rendr/shared/app') | |
, handlebarsHelpers = require('./lib/handlebarsHelpers') | |
, Polyglot = require('node-polyglot') | |
, _ = require('underscore'); | |
/** | |
* setup constants/globals | |
*/ | |
var isServer = typeof window === 'undefined' | |
, root = isServer ? global : window; | |
_.extend(root, { | |
IS_SERVER: isServer | |
}); | |
/** | |
* Extend the `BaseApp` class, adding any custom methods or overrides. | |
*/ | |
module.exports = BaseApp.extend({ | |
/** | |
* Client and server. | |
* | |
* `postInitialize` is called on app initialize, both on the client and server. | |
* On the server, an app is instantiated once for each request, and in the | |
* client, it's instantiated once on page load. | |
* | |
* This is a good place to initialize any code that needs to be available to | |
* app on both client and server. | |
*/ | |
initialize: function() { | |
/** | |
* Register our Handlebars helpers. | |
* | |
* `this.templateAdapter` is, by default, the `rendr-handlebars` module. | |
* It has a `registerHelpers` method, which allows us to register helper | |
* modules that can be used on both client & server. | |
*/ | |
this.templateAdapter.registerHelpers(handlebarsHelpers); | |
this.polyglot = new Polyglot(); | |
}, | |
// This is called directly on the server so we can use Polyglot | |
// during server rendering. | |
setPhrases: function(phrases) { | |
this.polyglot.extend(phrases); | |
}, | |
getCurrentLocale: function(){ | |
return this.polyglot.locale(); | |
}, | |
/** | |
* Client-side only. | |
* | |
* `start` is called at the bottom of `__layout.hbs`. Calling this kicks off | |
* the router and initializes the application. | |
* | |
* Override this method (remembering to call the superclass' `start` method!) | |
* in order to do things like bind events to the router, as shown below. | |
*/ | |
start: function() { | |
// This sets the phrases in the client-side so we can use Polyglot | |
// during client rendering. The phrases are accessible with | |
// `this.get('phrases')` because in the middleware (below) we set | |
// them as an app attribute. An app's attributes are serialized as | |
// JSON and bootstrapped to the client. | |
this.setPhrases( this.get('phrases') ); | |
this.router.on('action:start', this.routerStart, this); | |
this.router.on('action:end', this.routerEnd, this); | |
// Call 'super'. | |
BaseApp.prototype.start.call(this); | |
}, | |
/** | |
* Action on route start | |
*/ | |
routerStart: function(){ | |
this.set({loading: true}); | |
this.trigger('app:routerStart'); | |
}, | |
/** | |
* When route ends | |
*/ | |
routerEnd: function(){ | |
this.set({loading: false}); | |
this.trigger('app:routerEnd'); | |
}, | |
/** | |
* Inital setups/initlaizations used all over site | |
*/ | |
initialSetup: function(){ | |
$.ajaxSetup({ cache: false }); | |
}, | |
httpBuildQuery: function(objHash) { | |
return _.map(objHash, function(value, key) { | |
return key + '=' + value; | |
}).join('&'); | |
}, | |
/** | |
* Client-side only. | |
* | |
* This method also exists on shared/app.js, and is called by client/router. | |
* Override it here to specify your own app_view object. | |
*/ | |
getAppViewClass: function() { | |
return require('./views/app_view'); | |
}, | |
}); |
module.exports = function(Handlebars) { | |
var helpers = {}; | |
helpers.t = function (phrase, options) { | |
try{ | |
return this.app.polyglot.t(phrase, options.hash); | |
} | |
catch (err){ | |
return this._app.polyglot.t(phrase, options.hash); | |
} | |
}; | |
return helpers; | |
}; |
/** index.js **/ | |
var express = require('express'), | |
rendr = require('rendr'), | |
request = require('request'), | |
_ = require('underscore'); | |
var siteInfo = { | |
user: [], | |
catalog: [], | |
}; | |
/** | |
* | |
*/ | |
var config = require('config'); | |
/** | |
* | |
*/ | |
var app = express(); | |
/** | |
* stack | |
*/ | |
app.use(express.compress()); | |
app.use(express.static(__dirname + '/public')); | |
app.use(express.logger()); | |
app.use(express.bodyParser()); | |
app.use(function(req, res, next) { | |
res.header('Access-Control-Allow-Origin', '*'); | |
next(); | |
}); | |
app.use(express.cookieParser()); | |
var rendrServer = rendr.createServer({ | |
dataAdapterConfig: config.api, | |
appData: config.appData | |
}); | |
app.use(rendrServer); | |
//Get Language file based on currentLocale which is set in config/default.js | |
function getLocal(req, currentLocale, callback){ | |
var phrases = {}; | |
try { | |
phrases = require( './locales/' + currentLocale + '.json'); | |
} | |
catch (e) { | |
phrases = require( './locales/en.json'); | |
} | |
callback(null, phrases); | |
}; | |
rendrServer.configure(function(rendrExpressApp) { | |
rendrExpressApp.use(function(req, res, next) { | |
if (req.siteInfo && !req.rendrApp.get('siteInfo')) { | |
req.rendrApp.set('user', req.siteInfo); | |
} | |
var currentLocale = req.rendrApp.get('currentLocale'); | |
console.log('currentLocale=>',currentLocale); | |
// Fetch phrases from API or cache based on req. | |
// Example fake method: | |
getLocal(req, currentLocale, function(err, phrases) { | |
if (err) next(err); | |
// Set the phrases so they're usable on the server during | |
// view rendering, etc. | |
req.rendrApp.setPhrases(phrases); | |
// Now set them as app attributes so they get serialized and | |
// bootstrapped onto the page as JSON so we can use them in | |
// the client. | |
req.rendrApp.set({phrases: phrases}); | |
next(); | |
}); | |
}); | |
}); | |
p = process.env.PORT || config.server.port; | |
var httpServer = app.listen(p); | |
console.log('server listening on port ' + p + '......'); | |
//If process.exit(), do the cleanup | |
process.on('exit', function(code) { | |
console.log('About to exit with code:', code); | |
if (httpServer) { | |
console.log('Trying to close httpServer'); | |
httpServer.close(function() { | |
console.log('Expressjs http server close.'); | |
process.exit(2); | |
}); | |
} | |
}); | |
// catch ctrl+c event and exit normally // which calls process.exit() which eventually does cleanup | |
process.on('SIGINT', function() { | |
console.log('SIGINT --- '); | |
if (httpServer) { | |
httpServer.close(function() { | |
console.log('Expressjs http server close.'); | |
process.exit(2); | |
}); | |
} | |
}); | |
// catch ctrl+c event and exit normally // which calls process.exit() which eventually does cleanup | |
process.on('SIGTERM', function() { | |
console.log('SIGTERM --- '); | |
if (httpServer) { | |
httpServer.close(function() { | |
console.log('Expressjs http server close.'); | |
process.exit(2); | |
}); | |
} | |
}); | |
exports.app = app; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment