forked from knadh/listmonk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathi18n.go
100 lines (80 loc) · 2.45 KB
/
i18n.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package main
import (
"encoding/json"
"fmt"
"net/http"
"sort"
"github.com/knadh/listmonk/internal/i18n"
"github.com/knadh/stuffbin"
"github.com/labstack/echo/v4"
)
type i18nLang struct {
Code string `json:"code"`
Name string `json:"name"`
}
type i18nLangRaw struct {
Code string `json:"_.code"`
Name string `json:"_.name"`
}
// handleGetI18nLang returns the JSON language pack given the language code.
func handleGetI18nLang(c echo.Context) error {
app := c.Get("app").(*App)
lang := c.Param("lang")
if len(lang) > 6 || reLangCode.MatchString(lang) {
return echo.NewHTTPError(http.StatusBadRequest, "Invalid language code.")
}
i, ok, err := getI18nLang(lang, app.fs)
if err != nil && !ok {
return echo.NewHTTPError(http.StatusBadRequest, "Unknown language.")
}
return c.JSON(http.StatusOK, okResp{json.RawMessage(i.JSON())})
}
// getI18nLangList returns the list of available i18n languages.
func getI18nLangList(lang string, app *App) ([]i18nLang, error) {
list, err := app.fs.Glob("/i18n/*.json")
if err != nil {
return nil, err
}
var out []i18nLang
for _, l := range list {
b, err := app.fs.Get(l)
if err != nil {
return out, fmt.Errorf("error reading lang file: %s: %v", l, err)
}
var lang i18nLangRaw
if err := json.Unmarshal(b.ReadBytes(), &lang); err != nil {
return out, fmt.Errorf("error parsing lang file: %s: %v", l, err)
}
out = append(out, i18nLang{
Code: lang.Code,
Name: lang.Name,
})
}
sort.SliceStable(out, func(i, j int) bool {
return out[i].Code < out[j].Code
})
return out, nil
}
// The bool indicates whether the specified language could be loaded. If it couldn't
// be, the app shouldn't halt but throw a warning.
func getI18nLang(lang string, fs stuffbin.FileSystem) (*i18n.I18n, bool, error) {
const def = "en"
b, err := fs.Read(fmt.Sprintf("/i18n/%s.json", def))
if err != nil {
return nil, false, fmt.Errorf("error reading default i18n language file: %s: %v", def, err)
}
// Initialize with the default language.
i, err := i18n.New(b)
if err != nil {
return nil, false, fmt.Errorf("error unmarshalling i18n language: %s: %v", lang, err)
}
// Load the selected language on top of it.
b, err = fs.Read(fmt.Sprintf("/i18n/%s.json", lang))
if err != nil {
return i, true, fmt.Errorf("error reading i18n language file: %s: %v", lang, err)
}
if err := i.Load(b); err != nil {
return i, true, fmt.Errorf("error loading i18n language file: %s: %v", lang, err)
}
return i, true, nil
}