hexo
Version:
A fast, simple & powerful blog framework, powered by Node.js.
198 lines (163 loc) • 3.56 kB
JavaScript
var _ = require('lodash'),
vsprintf = require('sprintf-js').vsprintf;
/**
* i18n module.
*
* @class i18n
* @param {Object} [options]
* @param {String} [options.code=default]
* @constructor
* @module hexo
*/
var i18n = module.exports = function i18n(options){
/**
* Language data.
*
* @property data
* @type {Object}
*/
this.data = {};
/**
* Options
*
* @property options
* @type {Object}
*/
this.options = _.extend({
code: 'default'
}, options);
this.options.code = _getCodeToken(this.options.code);
};
/**
* Gets language data.
*
* @method get
* @param {String} code
* @return {Object}
*/
i18n.prototype.get = function(code){
return this.data[code];
};
/**
* Sets language data.
*
* @method set
* @param {String} code
* @param {Object} data
* @chainable
*/
i18n.prototype.set = function(code, data){
this.data[code] = data;
return this;
};
/**
* Removes language data.
*
* @method remove
* @param {String} code
* @chainable
*/
i18n.prototype.remove = function(code){
this.data[code] = null;
return this;
};
var _getProperty = function(obj, key){
if (!obj) return;
var keys = key.replace(/\[(\w+)\]/g, '.$1').split('.'),
cursor = obj;
for (var i = 0, len = keys.length; i < len; i++){
cursor = cursor[keys[i]];
if (typeof cursor === 'undefined') return;
}
return cursor;
};
var _getCodeToken = function(code){
var arr = [];
if (Array.isArray(code)){
code.forEach(function(item){
arr = arr.concat(_getCodeToken(item));
});
} else if (code){
var split = code.split('-');
arr.push(code);
for (var i = split.length - 1; i > 0; i--){
arr.push(split.slice(0, i).join('-'));
}
}
return arr;
};
/**
* Parses the language code.
*
* @method _parseCode
* @param {String|Array} code
* @return {Array}
*/
i18n.prototype._parseCode = function(code){
var arr = [].concat(_getCodeToken(code), this.options.code);
if (arr.indexOf('default') === -1){
arr.push('default');
}
return _.uniq(arr);
};
/**
* Returns a function for translation.
*
* @method __
* @param {String|Array} [code]
* @return {Function}
*/
i18n.prototype.__ = function(code){
var data = this.data,
langs = this._parseCode(code),
length = langs.length;
var __ = function(){
var args = _.toArray(arguments),
key = args.shift(),
str = '';
for (var i = 0; i < length; i++){
str = _getProperty(data[langs[i]], key);
if (str) break;
}
if (!str || typeof str !== 'string') str = key;
return vsprintf(str, args);
};
__.languages = langs;
return __;
};
/**
* Returns a function for plural translation.
*
* @method _p
* @param {String|Array} [code]
* @return {Function}
*/
i18n.prototype._p = function(code){
var data = this.data,
langs = this._parseCode(code),
length = langs.length;
var _p = function(){
var args = _.toArray(arguments),
key = args.shift(),
number = parseInt(args[0], 10),
str = '',
plural;
for (var i = 0; i < length; i++){
plural = _getProperty(data[langs[i]], key);
if (plural) break;
}
if (plural){
if (number === 0 && plural.hasOwnProperty('zero')){
str = plural.zero;
} else if (number === 1 && plural.hasOwnProperty('one')){
str = plural.one;
} else if (plural.hasOwnProperty('other')){
str = plural.other;
}
}
if (!str || typeof str !== 'string') str = key;
return vsprintf(str || key, args);
};
_p.languages = langs;
return _p;
};