localization.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. const _ = require('lodash')
  2. const dotize = require('dotize')
  3. const i18nMW = require('i18next-express-middleware')
  4. const i18next = require('i18next')
  5. const Promise = require('bluebird')
  6. /* global WIKI */
  7. module.exports = {
  8. engine: null,
  9. namespaces: [],
  10. init() {
  11. this.namespaces = WIKI.data.localeNamespaces
  12. this.engine = i18next
  13. this.engine.init({
  14. load: 'languageOnly',
  15. ns: this.namespaces,
  16. defaultNS: 'common',
  17. saveMissing: false,
  18. lng: WIKI.config.site.lang,
  19. fallbackLng: 'en'
  20. })
  21. // Load fallback defaults
  22. const enFallback = require('../locales/default.json')
  23. if (_.isPlainObject(enFallback)) {
  24. _.forOwn(enFallback, (data, ns) => {
  25. this.namespaces.push(ns)
  26. this.engine.addResourceBundle('en', ns, data)
  27. })
  28. }
  29. // Load current language
  30. this.loadLocale(WIKI.config.site.lang, { silent: true })
  31. return this
  32. },
  33. attachMiddleware (app) {
  34. app.use(i18nMW.handle(this.engine))
  35. },
  36. async getByNamespace(locale, namespace) {
  37. if (this.engine.hasResourceBundle(locale, namespace)) {
  38. let data = this.engine.getResourceBundle(locale, namespace)
  39. return _.map(dotize.convert(data), (value, key) => {
  40. return {
  41. key,
  42. value
  43. }
  44. })
  45. } else {
  46. throw new Error('Invalid locale or namespace')
  47. }
  48. },
  49. async loadLocale(locale, opts = { silent: false }) {
  50. const res = await WIKI.db.Locale.findOne({
  51. where: {
  52. code: locale
  53. }
  54. })
  55. if (res) {
  56. if (_.isPlainObject(res.strings)) {
  57. _.forOwn(res.strings, (data, ns) => {
  58. this.namespaces.push(ns)
  59. this.engine.addResourceBundle(locale, ns, data, true, true)
  60. })
  61. }
  62. } else if (!opts.silent) {
  63. throw new Error('No such locale in local store.')
  64. }
  65. },
  66. async setCurrentLocale(locale) {
  67. return Promise.fromCallback(cb => {
  68. return this.engine.changeLanguage(locale, cb)
  69. })
  70. }
  71. }