121 行
3.3 KiB
JavaScript
121 行
3.3 KiB
JavaScript
// Lightweight i18n for WeChat Mini Program (no official i18n API).
|
|
//
|
|
// Usage in a page:
|
|
// var i18n = require('../../i18n/index')
|
|
// onShow: function () { i18n.bind(this) } // injects `i18n` + `locale` into page data
|
|
// WXML: {{i18n.common.loading}} / {{i18n.profile.title}}
|
|
// JS strings: i18n.t('common.loading')
|
|
//
|
|
// Locale is persisted in storage; switching locale notifies listeners and the
|
|
// convention is that every page re-runs i18n.bind(this) in onShow, so tab pages
|
|
// pick up the new language the next time they are shown.
|
|
|
|
var locales = require('./locales/index')
|
|
|
|
var STORAGE_KEY = 'app_locale'
|
|
var DEFAULT_LOCALE = 'zh'
|
|
var SUPPORTED = ['zh', 'en']
|
|
var LOCALE_NAMES = { zh: '中文', en: 'English' }
|
|
|
|
var _listeners = []
|
|
var _current = null
|
|
|
|
function getSystemLocale() {
|
|
try {
|
|
var sys = wx.getSystemInfoSync()
|
|
var lang = (sys.language || '').toLowerCase()
|
|
return lang.indexOf('en') === 0 ? 'en' : 'zh'
|
|
} catch (e) {
|
|
return DEFAULT_LOCALE
|
|
}
|
|
}
|
|
|
|
function getLocale() {
|
|
if (_current) return _current
|
|
var saved = ''
|
|
try { saved = wx.getStorageSync(STORAGE_KEY) } catch (e) {}
|
|
_current = SUPPORTED.indexOf(saved) !== -1 ? saved : getSystemLocale()
|
|
return _current
|
|
}
|
|
|
|
function setLocale(locale) {
|
|
if (SUPPORTED.indexOf(locale) === -1 || locale === _current) return
|
|
_current = locale
|
|
try { wx.setStorageSync(STORAGE_KEY, locale) } catch (e) {}
|
|
applyTabBar()
|
|
for (var i = 0; i < _listeners.length; i++) {
|
|
try { _listeners[i](locale) } catch (e) {}
|
|
}
|
|
}
|
|
|
|
function onChange(fn) { if (typeof fn === 'function') _listeners.push(fn) }
|
|
function offChange(fn) {
|
|
_listeners = _listeners.filter(function (f) { return f !== fn })
|
|
}
|
|
|
|
function getDict() {
|
|
var loc = getLocale()
|
|
return locales[loc] || locales[DEFAULT_LOCALE]
|
|
}
|
|
|
|
function _lookup(dict, key) {
|
|
if (!dict) return undefined
|
|
var parts = key.split('.')
|
|
var cur = dict
|
|
for (var i = 0; i < parts.length; i++) {
|
|
if (cur == null) return undefined
|
|
cur = cur[parts[i]]
|
|
}
|
|
return cur
|
|
}
|
|
|
|
// t('profile.title', {name: 'x'}) — falls back to zh, then to the raw key.
|
|
function t(key, params) {
|
|
var loc = getLocale()
|
|
var val = _lookup(locales[loc], key)
|
|
if (val === undefined) val = _lookup(locales[DEFAULT_LOCALE], key)
|
|
if (typeof val !== 'string') return val === undefined ? key : val
|
|
if (params) {
|
|
val = val.replace(/\{(\w+)\}/g, function (m, k) {
|
|
return params[k] !== undefined ? params[k] : m
|
|
})
|
|
}
|
|
return val
|
|
}
|
|
|
|
// Inject the full dictionary + current locale into a page/component's data.
|
|
function bind(page) {
|
|
if (page && typeof page.setData === 'function') {
|
|
page.setData({ i18n: getDict(), locale: getLocale() })
|
|
}
|
|
}
|
|
|
|
// Refresh the bottom tabBar labels to the current locale.
|
|
function applyTabBar() {
|
|
var d = getDict()
|
|
var tab = (d && d.common && d.common.tab) || {}
|
|
var items = [
|
|
{ index: 0, text: tab.home },
|
|
{ index: 1, text: tab.records },
|
|
{ index: 2, text: tab.mine }
|
|
]
|
|
items.forEach(function (it) {
|
|
if (!it.text) return
|
|
wx.setTabBarItem({ index: it.index, text: it.text, fail: function () {} })
|
|
})
|
|
}
|
|
|
|
module.exports = {
|
|
SUPPORTED: SUPPORTED,
|
|
LOCALE_NAMES: LOCALE_NAMES,
|
|
getLocale: getLocale,
|
|
setLocale: setLocale,
|
|
getSystemLocale: getSystemLocale,
|
|
onChange: onChange,
|
|
offChange: offChange,
|
|
getDict: getDict,
|
|
bind: bind,
|
|
applyTabBar: applyTabBar,
|
|
t: t
|
|
}
|