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:
parent
55e21f8be3
commit
3273607fc3
2
lang.go
2
lang.go
@ -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 {
|
||||||
|
74
setup.go
74
setup.go
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
304
storage.go
304
storage.go
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user