From 3296649caeb200dbbb640359a783d1fa997f7d09 Mon Sep 17 00:00:00 2001 From: Maxim Lebedev Date: Sat, 11 Nov 2023 23:53:58 +0600 Subject: [PATCH] :building_construction: Use subfolders for translations --- internal/common/common.go | 9 ++++---- main.go | 48 +++++++++++++++++++++++++++++++++++---- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/internal/common/common.go b/internal/common/common.go index dc060a3..e818105 100644 --- a/internal/common/common.go +++ b/internal/common/common.go @@ -1,13 +1,14 @@ package common const ( - HeaderAcceptLanguage string = "Accept-Language" - HeaderContentType string = "Content-Type" + HeaderAcceptLanguage string = "Accept-Language" + HeaderContentLanguage string = "Content-Language" + HeaderContentType string = "Content-Type" ) const ( - MIMETextHTML string = "text/html" - MIMETextHTMLCharsetUTF8 string = MIMETextHTML + "; " + charsetUTF8 + MIMETextHTML string = "text/html" + MIMETextHTMLCharsetUTF8 string = MIMETextHTML + "; " + charsetUTF8 ) const charsetUTF8 string = "charset=UTF-8" diff --git a/main.go b/main.go index 6259c66..9b2333c 100644 --- a/main.go +++ b/main.go @@ -18,6 +18,7 @@ import ( "path/filepath" "runtime" "runtime/pprof" + "strings" "syscall" "time" _ "time/tzdata" @@ -38,6 +39,7 @@ import ( "source.toby3d.me/toby3d/home/internal/templateutil" themefsrepo "source.toby3d.me/toby3d/home/internal/theme/repository/fs" themeucase "source.toby3d.me/toby3d/home/internal/theme/usecase" + "source.toby3d.me/toby3d/home/internal/urlutil" ) type ( @@ -81,12 +83,42 @@ func NewApp(ctx context.Context, config *domain.Config) (*App, error) { server := &http.Server{ Addr: config.AddrPort().String(), Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - tags, _, err := language.ParseAcceptLanguage(r.Header.Get(common.HeaderAcceptLanguage)) - if err != nil || len(tags) == 0 { - tags = append(tags, language.English) + head, tail := urlutil.ShiftPath(r.URL.Path) + + if head == "" { + tags, _, err := language.ParseAcceptLanguage(r.Header.Get(common.HeaderAcceptLanguage)) + if err != nil || len(tags) == 0 { + tags = append(tags, language.English) + } + + lang, _, _ := matcher.Match(tags...) + + http.Redirect(w, r, "/"+lang.String()+"/", http.StatusSeeOther) + + return } - lang, _, _ := matcher.Match(tags...) + lang, err := language.Parse(head) + if err != nil || lang == language.Und { + res, err := staticer.Do(r.Context(), r.URL.Path) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + http.Error(w, err.Error(), http.StatusNotFound) + + return + } + + http.Error(w, err.Error(), http.StatusInternalServerError) + + return + } + + http.ServeContent(w, r, res.Name(), domain.ResourceModTime(res), res) + + return + } + + r.URL.Path = tail s, err := siter.Do(r.Context(), lang) if err != nil { @@ -121,6 +153,14 @@ func NewApp(ctx context.Context, config *domain.Config) (*App, error) { return } + contentLanguage := make([]string, len(p.Translations)) + for i := range p.Translations { + base, _ := p.Translations[i].Language.Base() + contentLanguage[i] = base.String() + } + + w.Header().Set(common.HeaderContentLanguage, strings.Join(contentLanguage, ", ")) + tpl, err := themer.Do(r.Context()) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError)