1
0
mirror of https://github.com/hrfee/jfa-go.git synced 2024-12-22 17:10:10 +00:00

translation: add fallback option to langMeta

If set to a language code (e.g fr-fr), any missing strings will be
filled in from that language (if possible) rather than from the default
en-us. Currently not used, but could be useful in the future for
variations of the same language.
This commit is contained in:
Harvey Tindall 2021-04-13 18:34:13 +01:00
parent 55e21f8be3
commit 3273607fc3
Signed by: hrfee
GPG Key ID: BBC65952848FB1A2
3 changed files with 284 additions and 108 deletions

View File

@ -2,6 +2,8 @@ package main
type langMeta struct { type langMeta struct {
Name string `json:"name"` Name string `json:"name"`
// Language to fall back on if strings are missing. Defaults to en-us.
Fallback string `json:"fallback,omitempty"`
} }
type quantityString struct { type quantityString struct {

View File

@ -73,7 +73,10 @@ func (app *appContext) TestJF(gc *gin.Context) {
func (st *Storage) loadLangSetup(filesystems ...fs.FS) error { func (st *Storage) loadLangSetup(filesystems ...fs.FS) error {
st.lang.Setup = map[string]setupLang{} st.lang.Setup = map[string]setupLang{}
var english setupLang var english setupLang
load := func(filesystem fs.FS, fname string) error { loadedLangs := make([]map[string]bool, len(filesystems))
var load loadLangFunc
load = func(fsIndex int, fname string) error {
filesystem := filesystems[fsIndex]
index := strings.TrimSuffix(fname, filepath.Ext(fname)) index := strings.TrimSuffix(fname, filepath.Ext(fname))
lang := setupLang{} lang := setupLang{}
f, err := fs.ReadFile(filesystem, FSJoin(st.lang.SetupPath, fname)) f, err := fs.ReadFile(filesystem, FSJoin(st.lang.SetupPath, fname))
@ -84,21 +87,47 @@ func (st *Storage) loadLangSetup(filesystems ...fs.FS) error {
if err != nil { if err != nil {
return err return err
} }
st.lang.Common.patchCommon(index, &lang.Strings) st.lang.Common.patchCommon(&lang.Strings, index)
if fname != "en-us.json" { if fname != "en-us.json" {
patchLang(&english.Strings, &lang.Strings) if lang.Meta.Fallback != "" {
patchLang(&english.StartPage, &lang.StartPage) fallback, ok := st.lang.Setup[lang.Meta.Fallback]
patchLang(&english.Updates, &lang.Updates) err = nil
patchLang(&english.EndPage, &lang.EndPage) if !ok {
patchLang(&english.Language, &lang.Language) err = load(fsIndex, lang.Meta.Fallback+".json")
patchLang(&english.Login, &lang.Login) fallback = st.lang.Setup[lang.Meta.Fallback]
patchLang(&english.JellyfinEmby, &lang.JellyfinEmby) }
patchLang(&english.Email, &lang.Email) if err == nil {
patchLang(&english.Notifications, &lang.Notifications) loadedLangs[fsIndex][lang.Meta.Fallback+".json"] = true
patchLang(&english.PasswordResets, &lang.PasswordResets) patchLang(&lang.Strings, &fallback.Strings, &english.Strings)
patchLang(&english.InviteEmails, &lang.InviteEmails) patchLang(&lang.StartPage, &fallback.StartPage, &english.StartPage)
patchLang(&english.PasswordValidation, &lang.PasswordValidation) patchLang(&lang.Updates, &fallback.Updates, &english.Updates)
patchLang(&english.HelpMessages, &lang.HelpMessages) patchLang(&lang.EndPage, &fallback.EndPage, &english.EndPage)
patchLang(&lang.Language, &fallback.Language, &english.Language)
patchLang(&lang.Login, &fallback.Login, &english.Login)
patchLang(&lang.JellyfinEmby, &fallback.JellyfinEmby, &english.JellyfinEmby)
patchLang(&lang.Email, &fallback.Email, &english.Email)
patchLang(&lang.Notifications, &fallback.Notifications, &english.Notifications)
patchLang(&lang.PasswordResets, &fallback.PasswordResets, &english.PasswordResets)
patchLang(&lang.InviteEmails, &fallback.InviteEmails, &english.InviteEmails)
patchLang(&lang.PasswordValidation, &fallback.PasswordValidation, &english.PasswordValidation)
patchLang(&lang.HelpMessages, &fallback.HelpMessages, &english.HelpMessages)
}
}
if (lang.Meta.Fallback != "" && err != nil) || lang.Meta.Fallback == "" {
patchLang(&lang.Strings, &english.Strings)
patchLang(&lang.StartPage, &english.StartPage)
patchLang(&lang.Updates, &english.Updates)
patchLang(&lang.EndPage, &english.EndPage)
patchLang(&lang.Language, &english.Language)
patchLang(&lang.Login, &english.Login)
patchLang(&lang.JellyfinEmby, &english.JellyfinEmby)
patchLang(&lang.Email, &english.Email)
patchLang(&lang.Notifications, &english.Notifications)
patchLang(&lang.PasswordResets, &english.PasswordResets)
patchLang(&lang.InviteEmails, &english.InviteEmails)
patchLang(&lang.PasswordValidation, &english.PasswordValidation)
patchLang(&lang.HelpMessages, &english.HelpMessages)
}
} }
stringSettings, err := json.Marshal(lang) stringSettings, err := json.Marshal(lang)
if err != nil { if err != nil {
@ -110,27 +139,30 @@ func (st *Storage) loadLangSetup(filesystems ...fs.FS) error {
} }
engFound := false engFound := false
var err error var err error
for _, filesystem := range filesystems { for i := range filesystems {
err = load(filesystem, "en-us.json") loadedLangs[i] = map[string]bool{}
err = load(i, "en-us.json")
if err == nil { if err == nil {
engFound = true engFound = true
} }
loadedLangs[i]["en-us.json"] = true
} }
if !engFound { if !engFound {
return err return err
} }
english = st.lang.Setup["en-us"] english = st.lang.Setup["en-us"]
setupLoaded := false setupLoaded := false
for _, filesystem := range filesystems { for i := range filesystems {
files, err := fs.ReadDir(filesystem, st.lang.SetupPath) files, err := fs.ReadDir(filesystems[i], st.lang.SetupPath)
if err != nil { if err != nil {
return err return err
} }
for _, f := range files { for _, f := range files {
if f.Name() != "en-us.json" { if !loadedLangs[i][f.Name()] {
err = load(filesystem, f.Name()) err = load(i, f.Name())
if err == nil { if err == nil {
setupLoaded = true setupLoaded = true
loadedLangs[i][f.Name()] = true
} }
} }
} }

View File

@ -120,54 +120,86 @@ func (st *Storage) loadLang(filesystems ...fs.FS) (err error) {
return return
} }
func (common *commonLangs) patchCommon(lang string, other *langSection) { // The following patch* functions fill in a language with missing values
if *other == nil { // from a list of other sources in a preferred order.
*other = langSection{} // languages to patch from should be in decreasing priority,
// E.g: If to = fr-be, from = [fr-fr, en-us].
func (common *commonLangs) patchCommon(to *langSection, from ...string) {
if *to == nil {
*to = langSection{}
} }
if _, ok := (*common)[lang]; !ok { for n, ev := range (*common)[from[len(from)-1]].Strings {
lang = "en-us" if v, ok := (*to)[n]; !ok || v == "" {
i := 0
for i < len(from)-1 {
ev, ok = (*common)[from[i]].Strings[n]
if ok && ev != "" {
break
} }
for n, ev := range (*common)[lang].Strings { i++
if v, ok := (*other)[n]; !ok || v == "" { }
(*other)[n] = ev (*to)[n] = ev
} }
} }
} }
// If a given language has missing values, fill it in with the english value. func patchLang(to *langSection, from ...*langSection) {
func patchLang(english, other *langSection) { if *to == nil {
if *other == nil { *to = langSection{}
*other = langSection{}
} }
for n, ev := range *english { for n, ev := range *from[len(from)-1] {
if v, ok := (*other)[n]; !ok || v == "" { if v, ok := (*to)[n]; !ok || v == "" {
(*other)[n] = ev i := 0
for i < len(from)-1 {
ev, ok = (*from[i])[n]
if ok && ev != "" {
break
}
i++
}
(*to)[n] = ev
} }
} }
} }
func patchQuantityStrings(english, other *map[string]quantityString) { func patchQuantityStrings(to *map[string]quantityString, from ...*map[string]quantityString) {
if *other == nil { if *to == nil {
*other = map[string]quantityString{} *to = map[string]quantityString{}
}
for n, ev := range *from[len(from)-1] {
qs, ok := (*to)[n]
if !ok || qs.Singular == "" || qs.Plural == "" {
i := 0
subOk := false
for i < len(from)-1 {
ev, subOk = (*from[i])[n]
if subOk && ev.Singular != "" && ev.Plural != "" {
break
}
i++
} }
for n, ev := range *english {
qs, ok := (*other)[n]
if !ok { if !ok {
(*other)[n] = ev (*to)[n] = ev
continue continue
} else if qs.Singular == "" { } else if qs.Singular == "" {
qs.Singular = ev.Singular qs.Singular = ev.Singular
} else if (*other)[n].Plural == "" { } else if qs.Plural == "" {
qs.Plural = ev.Plural qs.Plural = ev.Plural
} }
(*other)[n] = qs (*to)[n] = qs
} }
} }
}
type loadLangFunc func(fsIndex int, name string) error
func (st *Storage) loadLangCommon(filesystems ...fs.FS) error { func (st *Storage) loadLangCommon(filesystems ...fs.FS) error {
st.lang.Common = map[string]commonLang{} st.lang.Common = map[string]commonLang{}
var english commonLang var english commonLang
load := func(filesystem fs.FS, fname string) error { loadedLangs := make([]map[string]bool, len(filesystems))
var load loadLangFunc
load = func(fsIndex int, fname string) error {
filesystem := filesystems[fsIndex]
index := strings.TrimSuffix(fname, filepath.Ext(fname)) index := strings.TrimSuffix(fname, filepath.Ext(fname))
lang := commonLang{} lang := commonLang{}
f, err := fs.ReadFile(filesystem, FSJoin(st.lang.CommonPath, fname)) f, err := fs.ReadFile(filesystem, FSJoin(st.lang.CommonPath, fname))
@ -182,34 +214,51 @@ func (st *Storage) loadLangCommon(filesystems ...fs.FS) error {
return err return err
} }
if fname != "en-us.json" { if fname != "en-us.json" {
patchLang(&english.Strings, &lang.Strings) if lang.Meta.Fallback != "" {
fallback, ok := st.lang.Common[lang.Meta.Fallback]
err = nil
if !ok {
err = load(fsIndex, lang.Meta.Fallback+".json")
fallback = st.lang.Common[lang.Meta.Fallback]
}
if err == nil {
loadedLangs[fsIndex][lang.Meta.Fallback+".json"] = true
patchLang(&lang.Strings, &fallback.Strings, &english.Strings)
}
}
if (lang.Meta.Fallback != "" && err != nil) || lang.Meta.Fallback == "" {
patchLang(&lang.Strings, &english.Strings)
}
} }
st.lang.Common[index] = lang st.lang.Common[index] = lang
return nil return nil
} }
engFound := false engFound := false
var err error var err error
for _, filesystem := range filesystems { for i := range filesystems {
err = load(filesystem, "en-us.json") loadedLangs[i] = map[string]bool{}
err = load(i, "en-us.json")
if err == nil { if err == nil {
engFound = true engFound = true
} }
loadedLangs[i]["en-us.json"] = true
} }
if !engFound { if !engFound {
return err return err
} }
english = st.lang.Common["en-us"] english = st.lang.Common["en-us"]
commonLoaded := false commonLoaded := false
for _, filesystem := range filesystems { for i := range filesystems {
files, err := fs.ReadDir(filesystem, st.lang.CommonPath) files, err := fs.ReadDir(filesystems[i], st.lang.CommonPath)
if err != nil { if err != nil {
continue continue
} }
for _, f := range files { for _, f := range files {
if f.Name() != "en-us.json" { if !loadedLangs[i][f.Name()] {
err = load(filesystem, f.Name()) err = load(i, f.Name())
if err == nil { if err == nil {
commonLoaded = true commonLoaded = true
loadedLangs[i][f.Name()] = true
} }
} }
} }
@ -223,7 +272,10 @@ func (st *Storage) loadLangCommon(filesystems ...fs.FS) error {
func (st *Storage) loadLangAdmin(filesystems ...fs.FS) error { func (st *Storage) loadLangAdmin(filesystems ...fs.FS) error {
st.lang.Admin = map[string]adminLang{} st.lang.Admin = map[string]adminLang{}
var english adminLang var english adminLang
load := func(filesystem fs.FS, fname string) error { loadedLangs := make([]map[string]bool, len(filesystems))
var load loadLangFunc
load = func(fsIndex int, fname string) error {
filesystem := filesystems[fsIndex]
index := strings.TrimSuffix(fname, filepath.Ext(fname)) index := strings.TrimSuffix(fname, filepath.Ext(fname))
lang := adminLang{} lang := adminLang{}
f, err := fs.ReadFile(filesystem, FSJoin(st.lang.AdminPath, fname)) f, err := fs.ReadFile(filesystem, FSJoin(st.lang.AdminPath, fname))
@ -237,11 +289,27 @@ func (st *Storage) loadLangAdmin(filesystems ...fs.FS) error {
if err != nil { if err != nil {
return err return err
} }
st.lang.Common.patchCommon(index, &lang.Strings) st.lang.Common.patchCommon(&lang.Strings, index)
if fname != "en-us.json" { if fname != "en-us.json" {
patchLang(&english.Strings, &lang.Strings) if lang.Meta.Fallback != "" {
patchLang(&english.Notifications, &lang.Notifications) fallback, ok := st.lang.Admin[lang.Meta.Fallback]
patchQuantityStrings(&english.QuantityStrings, &lang.QuantityStrings) err = nil
if !ok {
err = load(fsIndex, lang.Meta.Fallback+".json")
fallback = st.lang.Admin[lang.Meta.Fallback]
}
if err == nil {
loadedLangs[fsIndex][lang.Meta.Fallback+".json"] = true
patchLang(&lang.Strings, &fallback.Strings, &english.Strings)
patchLang(&lang.Notifications, &fallback.Notifications, &english.Notifications)
patchQuantityStrings(&lang.QuantityStrings, &fallback.QuantityStrings, &english.QuantityStrings)
}
}
if (lang.Meta.Fallback != "" && err != nil) || lang.Meta.Fallback == "" {
patchLang(&lang.Strings, &english.Strings)
patchLang(&lang.Notifications, &english.Notifications)
patchQuantityStrings(&lang.QuantityStrings, &english.QuantityStrings)
}
} }
stringAdmin, err := json.Marshal(lang) stringAdmin, err := json.Marshal(lang)
if err != nil { if err != nil {
@ -253,27 +321,30 @@ func (st *Storage) loadLangAdmin(filesystems ...fs.FS) error {
} }
engFound := false engFound := false
var err error var err error
for _, filesystem := range filesystems { for i := range filesystems {
err = load(filesystem, "en-us.json") loadedLangs[i] = map[string]bool{}
err = load(i, "en-us.json")
if err == nil { if err == nil {
engFound = true engFound = true
} }
loadedLangs[i]["en-us.json"] = true
} }
if !engFound { if !engFound {
return err return err
} }
english = st.lang.Admin["en-us"] english = st.lang.Admin["en-us"]
adminLoaded := false adminLoaded := false
for _, filesystem := range filesystems { for i := range filesystems {
files, err := fs.ReadDir(filesystem, st.lang.AdminPath) files, err := fs.ReadDir(filesystems[i], st.lang.AdminPath)
if err != nil { if err != nil {
continue continue
} }
for _, f := range files { for _, f := range files {
if f.Name() != "en-us.json" { if !loadedLangs[i][f.Name()] {
err = load(filesystem, f.Name()) err = load(i, f.Name())
if err == nil { if err == nil {
adminLoaded = true adminLoaded = true
loadedLangs[i][f.Name()] = true
} }
} }
} }
@ -287,7 +358,10 @@ func (st *Storage) loadLangAdmin(filesystems ...fs.FS) error {
func (st *Storage) loadLangForm(filesystems ...fs.FS) error { func (st *Storage) loadLangForm(filesystems ...fs.FS) error {
st.lang.Form = map[string]formLang{} st.lang.Form = map[string]formLang{}
var english formLang var english formLang
load := func(filesystem fs.FS, fname string) error { loadedLangs := make([]map[string]bool, len(filesystems))
var load loadLangFunc
load = func(fsIndex int, fname string) error {
filesystem := filesystems[fsIndex]
index := strings.TrimSuffix(fname, filepath.Ext(fname)) index := strings.TrimSuffix(fname, filepath.Ext(fname))
lang := formLang{} lang := formLang{}
f, err := fs.ReadFile(filesystem, FSJoin(st.lang.FormPath, fname)) f, err := fs.ReadFile(filesystem, FSJoin(st.lang.FormPath, fname))
@ -301,11 +375,27 @@ func (st *Storage) loadLangForm(filesystems ...fs.FS) error {
if err != nil { if err != nil {
return err return err
} }
st.lang.Common.patchCommon(index, &lang.Strings) st.lang.Common.patchCommon(&lang.Strings, index)
if fname != "en-us.json" { if fname != "en-us.json" {
patchLang(&english.Strings, &lang.Strings) if lang.Meta.Fallback != "" {
patchLang(&english.Notifications, &lang.Notifications) fallback, ok := st.lang.Form[lang.Meta.Fallback]
patchQuantityStrings(&english.ValidationStrings, &lang.ValidationStrings) err = nil
if !ok {
err = load(fsIndex, lang.Meta.Fallback+".json")
fallback = st.lang.Form[lang.Meta.Fallback]
}
if err == nil {
loadedLangs[fsIndex][lang.Meta.Fallback+".json"] = true
patchLang(&lang.Strings, &fallback.Strings, &english.Strings)
patchLang(&lang.Notifications, &fallback.Notifications, &english.Notifications)
patchQuantityStrings(&lang.ValidationStrings, &fallback.ValidationStrings, &english.ValidationStrings)
}
}
if (lang.Meta.Fallback != "" && err != nil) || lang.Meta.Fallback == "" {
patchLang(&lang.Strings, &english.Strings)
patchLang(&lang.Notifications, &english.Notifications)
patchQuantityStrings(&lang.ValidationStrings, &english.ValidationStrings)
}
} }
notifications, err := json.Marshal(lang.Notifications) notifications, err := json.Marshal(lang.Notifications)
if err != nil { if err != nil {
@ -322,27 +412,30 @@ func (st *Storage) loadLangForm(filesystems ...fs.FS) error {
} }
engFound := false engFound := false
var err error var err error
for _, filesystem := range filesystems { for i := range filesystems {
err = load(filesystem, "en-us.json") loadedLangs[i] = map[string]bool{}
err = load(i, "en-us.json")
if err == nil { if err == nil {
engFound = true engFound = true
} }
loadedLangs[i]["en-us.json"] = true
} }
if !engFound { if !engFound {
return err return err
} }
english = st.lang.Form["en-us"] english = st.lang.Form["en-us"]
formLoaded := false formLoaded := false
for _, filesystem := range filesystems { for i := range filesystems {
files, err := fs.ReadDir(filesystem, st.lang.FormPath) files, err := fs.ReadDir(filesystems[i], st.lang.FormPath)
if err != nil { if err != nil {
continue continue
} }
for _, f := range files { for _, f := range files {
if f.Name() != "en-us.json" { if !loadedLangs[i][f.Name()] {
err = load(filesystem, f.Name()) err = load(i, f.Name())
if err == nil { if err == nil {
formLoaded = true formLoaded = true
loadedLangs[i][f.Name()] = true
} }
} }
} }
@ -356,7 +449,10 @@ func (st *Storage) loadLangForm(filesystems ...fs.FS) error {
func (st *Storage) loadLangPWR(filesystems ...fs.FS) error { func (st *Storage) loadLangPWR(filesystems ...fs.FS) error {
st.lang.PasswordReset = map[string]pwrLang{} st.lang.PasswordReset = map[string]pwrLang{}
var english pwrLang var english pwrLang
load := func(filesystem fs.FS, fname string) error { loadedLangs := make([]map[string]bool, len(filesystems))
var load loadLangFunc
load = func(fsIndex int, fname string) error {
filesystem := filesystems[fsIndex]
index := strings.TrimSuffix(fname, filepath.Ext(fname)) index := strings.TrimSuffix(fname, filepath.Ext(fname))
lang := pwrLang{} lang := pwrLang{}
f, err := fs.ReadFile(filesystem, FSJoin(st.lang.PasswordResetPath, fname)) f, err := fs.ReadFile(filesystem, FSJoin(st.lang.PasswordResetPath, fname))
@ -370,36 +466,52 @@ func (st *Storage) loadLangPWR(filesystems ...fs.FS) error {
if err != nil { if err != nil {
return err return err
} }
st.lang.Common.patchCommon(index, &lang.Strings) st.lang.Common.patchCommon(&lang.Strings, index)
if fname != "en-us.json" { if fname != "en-us.json" {
patchLang(&english.Strings, &lang.Strings) if lang.Meta.Fallback != "" {
fallback, ok := st.lang.PasswordReset[lang.Meta.Fallback]
err = nil
if !ok {
err = load(fsIndex, lang.Meta.Fallback+".json")
fallback = st.lang.PasswordReset[lang.Meta.Fallback]
}
if err == nil {
patchLang(&lang.Strings, &fallback.Strings, &english.Strings)
}
}
if (lang.Meta.Fallback != "" && err != nil) || lang.Meta.Fallback == "" {
patchLang(&lang.Strings, &english.Strings)
}
} }
st.lang.PasswordReset[index] = lang st.lang.PasswordReset[index] = lang
return nil return nil
} }
engFound := false engFound := false
var err error var err error
for _, filesystem := range filesystems { for i := range filesystems {
err = load(filesystem, "en-us.json") loadedLangs[i] = map[string]bool{}
err = load(i, "en-us.json")
if err == nil { if err == nil {
engFound = true engFound = true
} }
loadedLangs[i]["en-us.json"] = true
} }
if !engFound { if !engFound {
return err return err
} }
english = st.lang.PasswordReset["en-us"] english = st.lang.PasswordReset["en-us"]
formLoaded := false formLoaded := false
for _, filesystem := range filesystems { for i := range filesystems {
files, err := fs.ReadDir(filesystem, st.lang.PasswordResetPath) files, err := fs.ReadDir(filesystems[i], st.lang.PasswordResetPath)
if err != nil { if err != nil {
continue continue
} }
for _, f := range files { for _, f := range files {
if f.Name() != "en-us.json" { if !loadedLangs[i][f.Name()] {
err = load(filesystem, f.Name()) err = load(i, f.Name())
if err == nil { if err == nil {
formLoaded = true formLoaded = true
loadedLangs[i][f.Name()] = true
} }
} }
} }
@ -413,7 +525,10 @@ func (st *Storage) loadLangPWR(filesystems ...fs.FS) error {
func (st *Storage) loadLangEmail(filesystems ...fs.FS) error { func (st *Storage) loadLangEmail(filesystems ...fs.FS) error {
st.lang.Email = map[string]emailLang{} st.lang.Email = map[string]emailLang{}
var english emailLang var english emailLang
load := func(filesystem fs.FS, fname string) error { loadedLangs := make([]map[string]bool, len(filesystems))
var load loadLangFunc
load = func(fsIndex int, fname string) error {
filesystem := filesystems[fsIndex]
index := strings.TrimSuffix(fname, filepath.Ext(fname)) index := strings.TrimSuffix(fname, filepath.Ext(fname))
lang := emailLang{} lang := emailLang{}
f, err := fs.ReadFile(filesystem, FSJoin(st.lang.EmailPath, fname)) f, err := fs.ReadFile(filesystem, FSJoin(st.lang.EmailPath, fname))
@ -427,46 +542,73 @@ func (st *Storage) loadLangEmail(filesystems ...fs.FS) error {
if err != nil { if err != nil {
return err return err
} }
st.lang.Common.patchCommon(index, &lang.Strings) st.lang.Common.patchCommon(&lang.Strings, index)
if fname != "en-us.json" { if fname != "en-us.json" {
patchLang(&english.UserCreated, &lang.UserCreated) if lang.Meta.Fallback != "" {
patchLang(&english.InviteExpiry, &lang.InviteExpiry) fallback, ok := st.lang.Email[lang.Meta.Fallback]
patchLang(&english.PasswordReset, &lang.PasswordReset) err = nil
patchLang(&english.UserDeleted, &lang.UserDeleted) if !ok {
patchLang(&english.UserDisabled, &lang.UserDisabled) err = load(fsIndex, lang.Meta.Fallback+".json")
patchLang(&english.UserEnabled, &lang.UserEnabled) fallback = st.lang.Email[lang.Meta.Fallback]
patchLang(&english.InviteEmail, &lang.InviteEmail) }
patchLang(&english.WelcomeEmail, &lang.WelcomeEmail) if err == nil {
patchLang(&english.EmailConfirmation, &lang.EmailConfirmation) loadedLangs[fsIndex][lang.Meta.Fallback+".json"] = true
patchLang(&english.UserExpired, &lang.UserExpired) patchLang(&lang.UserCreated, &fallback.UserCreated, &english.UserCreated)
patchLang(&english.Strings, &lang.Strings) patchLang(&lang.InviteExpiry, &fallback.InviteExpiry, &english.InviteExpiry)
patchLang(&lang.PasswordReset, &fallback.PasswordReset, &english.PasswordReset)
patchLang(&lang.UserDeleted, &fallback.UserDeleted, &english.UserDeleted)
patchLang(&lang.UserDisabled, &fallback.UserDisabled, &english.UserDisabled)
patchLang(&lang.UserEnabled, &fallback.UserEnabled, &english.UserEnabled)
patchLang(&lang.InviteEmail, &fallback.InviteEmail, &english.InviteEmail)
patchLang(&lang.WelcomeEmail, &fallback.WelcomeEmail, &english.WelcomeEmail)
patchLang(&lang.EmailConfirmation, &fallback.EmailConfirmation, &english.EmailConfirmation)
patchLang(&lang.UserExpired, &fallback.UserExpired, &english.UserExpired)
patchLang(&lang.Strings, &fallback.Strings, &english.Strings)
}
}
if (lang.Meta.Fallback != "" && err != nil) || lang.Meta.Fallback == "" {
patchLang(&lang.UserCreated, &english.UserCreated)
patchLang(&lang.InviteExpiry, &english.InviteExpiry)
patchLang(&lang.PasswordReset, &english.PasswordReset)
patchLang(&lang.UserDeleted, &english.UserDeleted)
patchLang(&lang.UserDisabled, &english.UserDisabled)
patchLang(&lang.UserEnabled, &english.UserEnabled)
patchLang(&lang.InviteEmail, &english.InviteEmail)
patchLang(&lang.WelcomeEmail, &english.WelcomeEmail)
patchLang(&lang.EmailConfirmation, &english.EmailConfirmation)
patchLang(&lang.UserExpired, &english.UserExpired)
patchLang(&lang.Strings, &english.Strings)
}
} }
st.lang.Email[index] = lang st.lang.Email[index] = lang
return nil return nil
} }
engFound := false engFound := false
var err error var err error
for _, filesystem := range filesystems { for i := range filesystems {
err = load(filesystem, "en-us.json") loadedLangs[i] = map[string]bool{}
err = load(i, "en-us.json")
if err == nil { if err == nil {
engFound = true engFound = true
} }
loadedLangs[i]["en-us.json"] = true
} }
if !engFound { if !engFound {
return err return err
} }
english = st.lang.Email["en-us"] english = st.lang.Email["en-us"]
emailLoaded := false emailLoaded := false
for _, filesystem := range filesystems { for i := range filesystems {
files, err := fs.ReadDir(filesystem, st.lang.EmailPath) files, err := fs.ReadDir(filesystems[i], st.lang.EmailPath)
if err != nil { if err != nil {
continue continue
} }
for _, f := range files { for _, f := range files {
if f.Name() != "en-us.json" { if !loadedLangs[i][f.Name()] {
err = load(filesystem, f.Name()) err = load(i, f.Name())
if err == nil { if err == nil {
emailLoaded = true emailLoaded = true
loadedLangs[i][f.Name()] = true
} }
} }
} }