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.

80 lines
2.2 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. 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.models.locales.query().findOne('code', locale)
  51. if (res) {
  52. if (_.isPlainObject(res.strings)) {
  53. _.forOwn(res.strings, (data, ns) => {
  54. this.namespaces.push(ns)
  55. this.engine.addResourceBundle(locale, ns, data, true, true)
  56. })
  57. }
  58. } else if (!opts.silent) {
  59. throw new Error('No such locale in local store.')
  60. }
  61. },
  62. async refreshNamespaces (silent = false) {
  63. await this.loadLocale(WIKI.config.lang.code, { silent })
  64. if (WIKI.config.lang.namespacing) {
  65. for (let ns of WIKI.config.lang.namespaces) {
  66. await this.loadLocale(ns, { silent })
  67. }
  68. }
  69. },
  70. async setCurrentLocale(locale) {
  71. await Promise.fromCallback(cb => {
  72. return this.engine.changeLanguage(locale, cb)
  73. })
  74. }
  75. }