You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.4 KiB

  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.lang.code,
  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 + namespaces
  30. this.refreshNamespaces(true)
  31. // Listen for localization events
  32. WIKI.events.on('localization', (action) => {
  33. switch (action) {
  34. case 'reload':
  35. this.refreshNamespaces()
  36. break
  37. }
  38. })
  39. return this
  40. },
  41. attachMiddleware (app) {
  42. app.use(i18nMW.handle(this.engine))
  43. },
  44. async getByNamespace(locale, namespace) {
  45. if (this.engine.hasResourceBundle(locale, namespace)) {
  46. let data = this.engine.getResourceBundle(locale, namespace)
  47. return _.map(dotize.convert(data), (value, key) => {
  48. return {
  49. key,
  50. value
  51. }
  52. })
  53. } else {
  54. throw new Error('Invalid locale or namespace')
  55. }
  56. },
  57. async loadLocale(locale, opts = { silent: false }) {
  58. const res = await WIKI.models.locales.query().findOne('code', locale)
  59. if (res) {
  60. if (_.isPlainObject(res.strings)) {
  61. _.forOwn(res.strings, (data, ns) => {
  62. this.namespaces.push(ns)
  63. this.engine.addResourceBundle(locale, ns, data, true, true)
  64. })
  65. }
  66. } else if (!opts.silent) {
  67. throw new Error('No such locale in local store.')
  68. }
  69. },
  70. async refreshNamespaces (silent = false) {
  71. await this.loadLocale(WIKI.config.lang.code, { silent })
  72. if (WIKI.config.lang.namespacing) {
  73. for (let ns of WIKI.config.lang.namespaces) {
  74. await this.loadLocale(ns, { silent })
  75. }
  76. }
  77. },
  78. async setCurrentLocale(locale) {
  79. await Promise.fromCallback(cb => {
  80. return this.engine.changeLanguage(locale, cb)
  81. })
  82. }
  83. }