feat(i18n): populate frontend datetime locale from backend settings

This commit is contained in:
Gregor Kleen 2019-10-29 15:54:11 +01:00
parent 83a458ddf5
commit 498d6168a0
6 changed files with 44 additions and 12 deletions

View File

@ -1,3 +1,5 @@
import moment from 'moment';
/**
* I18n
*
@ -13,10 +15,15 @@
export class I18n {
translations = {};
_translations = {};
_datetimeLocale = undefined;
add(id, translation) {
this.translations[id] = translation;
if (!this._translations[id]) {
this._translations[id] = translation;
} else {
throw new Error('I18N Error: Attempting to set translation multiple times for »' + id + '«!');
}
}
addMany(manyTranslations) {
@ -24,9 +31,27 @@ export class I18n {
}
get(id) {
if (!this.translations[id]) {
if (!this._translations[id]) {
throw new Error('I18N Error: Translation missing for »' + id + '«!');
}
return this.translations[id];
return this._translations[id];
}
setDatetimeLocale(locale) {
if (!this._datetimeLocale) {
moment.locale(locale);
this._datetimeLocale = locale;
} else {
throw new Error('I18N Error: Attempting to set datetime locale multiple times!');
}
}
getDatetimeLocale() {
if (!this._datetimeLocale) {
throw new Error('I18N Error: Attempting to access datetime locale when it has not been set!');
}
return this._datetimeLocale;
}
}

View File

@ -48,9 +48,6 @@ const DATEPICKER_CONFIG = {
timeMinutes: 0,
timeSeconds: 0,
// german settings
// TODO: hardcoded, get from current language / settings
locale: 'de',
weekStart: 1,
dateFormat: FORM_DATE_FORMAT_DATE_DT,
timeFormat: FORM_DATE_FORMAT_TIME_DT,
@ -86,6 +83,7 @@ export class Datepicker {
datepickerInstance;
_element;
elementType;
_locale;
constructor(element) {
if (!element) {
@ -96,6 +94,8 @@ export class Datepicker {
return false;
}
this._locale = window.App.i18n.getDatetimeLocale();
// initialize datepickerCollections singleton if not already done
if (!Datepicker.datepickerCollections) {
Datepicker.datepickerCollections = new Map();
@ -134,7 +134,7 @@ export class Datepicker {
}
// initialize tail.datetime (datepicker) instance and let it do weird stuff with the element value
this.datepickerInstance = datetime(this._element, { ...datepickerGlobalConfig, ...datepickerConfig });
this.datepickerInstance = datetime(this._element, { ...datepickerGlobalConfig, ...datepickerConfig, locale: this._locale });
// reset date to something sane
if (parsedMomentDate)

View File

@ -1930,6 +1930,7 @@ siteLayout' headingOverride widget = do
let
-- See Utils.Frontend.I18n and files in messages/frontend for message definitions
frontendI18n = toJSON (mr :: FrontendMessage -> Text)
frontendDatetimeLocale <- toJSON <$> selectLanguage frontendDatetimeLocales
pc <- widgetToPageContent $ do
-- fonts

View File

@ -1,5 +1,6 @@
module Utils.Frontend.I18n
( FrontendMessage(..)
, frontendDatetimeLocales
) where
import ClassyPrelude
@ -14,6 +15,9 @@ import Data.Aeson.Types (toJSONKeyText)
import Data.Aeson.TH
import qualified Data.Char as Char
import Data.List.NonEmpty (NonEmpty(..))
import Text.Shakespeare.I18N (Lang)
-- | I18n-Messages used in JavaScript-Frontend
--
@ -39,3 +43,7 @@ instance ToJSONKey FrontendMessage where
toJSONKey = toJSONKeyText toPathPiece
instance FromJSONKey FrontendMessage where
fromJSONKey = FromJSONKeyTextParser $ parseJSON . String
frontendDatetimeLocales :: NonEmpty Lang
frontendDatetimeLocales = "de" :| ["en"]

View File

@ -11,8 +11,6 @@ import qualified Data.List as List
import qualified Data.CaseInsensitive as CI
import Control.Lens (none)
import Yesod.Core.Types (HandlerData(handlerRequest), YesodRequest(reqLangs))
import qualified Network.Wai.Parse as NWP
@ -41,7 +39,7 @@ selectLanguages avL (l:ls)
, l'' <- matchesFor l'
, langMatches lParts' l''
]
= let now = nonEmpty . filter (\l' -> none (((==) `on` CI.mk) l') ls) $ sortOn (Down . length) found
= let now = nonEmpty $ sortOn (Down . length) found
others = selectLanguages avL ls
in maybe id (\now' others' -> NonEmpty.fromList $ toList now' ++ filter (`notElem` toList now') (toList others')) now others
| otherwise = selectLanguages avL ls

View File

@ -1,6 +1,6 @@
if (window.App) {
window.App.i18n.addMany(#{frontendI18n});
// window.App.i18n.setLang(lang); TODO: set language string for datepicker config
window.App.i18n.setDatetimeLocale(#{frontendDatetimeLocale});
} else {
throw new Error('I18n JavaScript service is missing!');
}