浏览代码

feat: sync locales strings

NGPixel 7 年之前
父节点
当前提交
b143aa2f8c

+ 28 - 4
server/core/localization.js

@@ -17,10 +17,22 @@ module.exports = {
       ns: this.namespaces,
       defaultNS: 'common',
       saveMissing: false,
-      preload: [WIKI.config.site.lang],
       lng: WIKI.config.site.lang,
       fallbackLng: 'en'
     })
+
+    // Load fallback defaults
+    const enFallback = require('../locales/default.json')
+    if (_.isPlainObject(enFallback)) {
+      _.forOwn(enFallback, (data, ns) => {
+        this.namespaces.push(ns)
+        this.engine.addResourceBundle('en', ns, data)
+      })
+    }
+
+    // Load current language
+    this.loadLocale(WIKI.config.site.lang, { silent: true })
+
     return this
   },
   attachMiddleware (app) {
@@ -39,10 +51,22 @@ module.exports = {
       throw new Error('Invalid locale or namespace')
     }
   },
-  async loadLocale(locale) {
-    return Promise.fromCallback(cb => {
-      return this.engine.loadLanguages(locale, cb)
+  async loadLocale(locale, opts = { silent: false }) {
+    const res = await WIKI.db.Locale.findOne({
+      where: {
+        code: locale
+      }
     })
+    if (res) {
+      if (_.isPlainObject(res.strings)) {
+        _.forOwn(res.strings, (data, ns) => {
+          this.namespaces.push(ns)
+          this.engine.addResourceBundle(locale, ns, data, true, true)
+        })
+      }
+    } else if (!opts.silent) {
+      throw new Error('No such locale in local store.')
+    }
   },
   async setCurrentLocale(locale) {
     return Promise.fromCallback(cb => {

+ 6 - 0
server/graph/resolvers/localization.js

@@ -28,6 +28,12 @@ module.exports = {
           installDate: isInstalled ? _.find(localLocales, ['code', rl.code]).updatedAt : null
         }
       })
+    },
+    async config(obj, args, context, info) {
+      return {
+        locale: WIKI.config.site.lang,
+        autoUpdate: WIKI.config.site.langAutoUpdate
+      }
     }
   },
   LocalizationMutation: {

+ 6 - 0
server/graph/schemas/localization.graphql

@@ -16,6 +16,7 @@ extend type Mutation {
 
 type LocalizationQuery {
   locales: [LocalizationLocale]
+  config: LocalizationConfig
 }
 
 # -----------------------------------------------
@@ -43,3 +44,8 @@ type LocalizationLocale {
   nativeName: String!
   updatedAt: Date!
 }
+
+type LocalizationConfig {
+  locale: String!
+  autoUpdate: Boolean!
+}

+ 38 - 2
server/jobs/sync-graph-locales.js

@@ -5,6 +5,8 @@ const { createApolloFetch } = require('apollo-fetch')
 /* global WIKI */
 
 WIKI.redis = require('../core/redis').init()
+WIKI.db = require('../core/db').init()
+
 const apollo = createApolloFetch({
   uri: 'https://graph.requarks.io'
 })
@@ -13,7 +15,11 @@ module.exports = async (job) => {
   WIKI.logger.info('Syncing locales with Graph endpoint...')
 
   try {
-    const resp = await apollo({
+    await WIKI.configSvc.loadFromDb(['site'])
+
+    // -> Fetch locales list
+
+    const respList = await apollo({
       query: `{
         localization {
           locales {
@@ -27,8 +33,38 @@ module.exports = async (job) => {
         }
       }`
     })
-    const locales = _.sortBy(_.get(resp, 'data.localization.locales', []), 'name').map(lc => ({...lc, isInstalled: (lc.code === 'en')}))
+    const locales = _.sortBy(_.get(respList, 'data.localization.locales', []), 'name').map(lc => ({...lc, isInstalled: (lc.code === 'en')}))
     WIKI.redis.set('locales', JSON.stringify(locales))
+    const currentLocale = _.find(locales, ['code', WIKI.config.site.lang])
+
+    // -> Download locale strings
+
+    if (WIKI.config.site.langAutoUpdate) {
+      const respStrings = await apollo({
+        query: `{
+          localization {
+            strings(code: "${WIKI.config.site.lang}") {
+              key
+              value
+            }
+          }
+        }`
+      })
+      const strings = _.get(respStrings, 'data.localization.strings', [])
+      let lcObj = {}
+      _.forEach(strings, row => {
+        if (_.includes(row.key, '::')) { return }
+        _.set(lcObj, row.key.replace(':', '.'), row.value)
+      })
+
+      WIKI.db.Locale.upsert({
+        code: WIKI.config.site.lang,
+        strings: lcObj,
+        isRTL: currentLocale.isRTL,
+        name: currentLocale.name,
+        nativeName: currentLocale.nativeName
+      })
+    }
 
     WIKI.logger.info('Syncing locales with Graph endpoint: [ COMPLETED ]')
   } catch (err) {

+ 2 - 1
server/setup.js

@@ -284,7 +284,8 @@ module.exports = () => {
       // Site namespace
       _.set(WIKI.config.site, 'title', req.body.title)
       _.set(WIKI.config.site, 'lang', 'en')
-      _.set(WIKI.config.site, 'rtl', _.includes(WIKI.data.rtlLangs, req.body.lang))
+      _.set(WIKI.config.site, 'langAutoUpdate', true)
+      _.set(WIKI.config.site, 'rtl', false)
       _.set(WIKI.config.site, 'sessionSecret', (await crypto.randomBytesAsync(32)).toString('hex'))
 
       // Auth namespace