Repository navigation
Expand file tree
/
Copy pathi18n.js
More file actions
133 lines (112 loc) · 4.54 KB
/
Copy pathi18n.js
File metadata and controls
133 lines (112 loc) · 4.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* global Intl */
var supportedLocales = ['en'],
_ = require('lodash'),
fs = require('fs'),
chalk = require('chalk'),
MessageFormat = require('intl-messageformat'),
logging = require('./logging'),
errors = require('./errors'),
// TODO: fetch this dynamically based on overall blog settings (`key = "default_locale"`) in the `settings` table
currentLocale = 'en',
blos,
I18n;
I18n = {
/**
* Helper method to find and compile the given data context with a proper string resource.
*
* @param {string} path Path with in the JSON language file to desired string (ie: "errors.init.jsNotBuilt")
* @param {object} [bindings]
* @returns {string}
*/
t: function t(path, bindings) {
var string = I18n.findString(path),
msg;
// If the path returns an array (as in the case with anything that has multiple paragraphs such as emails), then
// loop through them and return an array of translated/formatted strings. Otherwise, just return the normal
// translated/formatted string.
if (_.isArray(string)) {
msg = [];
string.forEach(function (s) {
var m = new MessageFormat(s, currentLocale);
msg.push(m.format(bindings));
});
} else {
msg = new MessageFormat(string, currentLocale);
msg = msg.format(bindings);
}
return msg;
},
/**
* Parse JSON file for matching locale, returns string giving path.
*
* @param {string} msgPath Path with in the JSON language file to desired string (ie: "errors.init.jsNotBuilt")
* @returns {string}
*/
findString: function findString(msgPath, opts) {
var options = _.merge({log: true}, opts || {}),
matchingString, path;
// no path? no string
if (_.isEmpty(msgPath) || !_.isString(msgPath)) {
chalk.yellow('i18n:t() - received an empty path.');
return '';
}
if (blos === undefined) {
I18n.init();
}
matchingString = blos;
path = msgPath.split('.');
path.forEach(function (key) {
// reassign matching object, or set to an empty string if there is no match
matchingString = matchingString[key] || {};
});
if (_.isObject(matchingString) || _.isEqual(matchingString, {})) {
if (options.log) {
logging.error(new errors.IncorrectUsageError({
message: `i18n error: path "${msgPath}" was not found`
}));
}
matchingString = blos.errors.errors.anErrorOccurred;
}
return matchingString;
},
doesTranslationKeyExist: function doesTranslationKeyExist(msgPath) {
var translation = I18n.findString(msgPath, {log: false});
return translation !== blos.errors.errors.anErrorOccurred;
},
/**
* Setup i18n support:
* - Load proper language file in to memory
* - Polyfill node.js if it does not have Intl support or support for a particular locale
*/
init: function init() {
// read file for current locale and keep its content in memory
blos = fs.readFileSync(__dirname + '/translations/' + currentLocale + '.json');
// if translation file is not valid, you will see an error
try {
blos = JSON.parse(blos);
} catch (err) {
blos = undefined;
throw err;
}
if (global.Intl) {
// Determine if the built-in `Intl` has the locale data we need.
var hasBuiltInLocaleData,
IntlPolyfill;
hasBuiltInLocaleData = supportedLocales.every(function (locale) {
return Intl.NumberFormat.supportedLocalesOf(locale)[0] === locale &&
Intl.DateTimeFormat.supportedLocalesOf(locale)[0] === locale;
});
if (!hasBuiltInLocaleData) {
// `Intl` exists, but it doesn't have the data we need, so load the
// polyfill and replace the constructors with need with the polyfill's.
IntlPolyfill = require('intl');
Intl.NumberFormat = IntlPolyfill.NumberFormat;
Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat;
}
} else {
// No `Intl`, so use and load the polyfill.
global.Intl = require('intl');
}
}
};
module.exports = I18n;