Introduce i18n. Теперь переведу сайт на русский!
This commit is contained in:
parent
4b351ed7a9
commit
50ba6bb74b
@ -15,8 +15,10 @@ import (
|
||||
"git.arav.su/Arav/dwelling-home/internal/version"
|
||||
mfsqlite "git.arav.su/Arav/dwelling-home/pkg/mindflow/database/sqlite"
|
||||
"git.arav.su/Arav/dwelling-home/web"
|
||||
"git.arav.su/Arav/dwelling-home/web/locales"
|
||||
"git.arav.su/Arav/httpr"
|
||||
gb "git.arav.su/Arav/justguestbook"
|
||||
"github.com/invopop/ctxi18n"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -50,6 +52,10 @@ func main() {
|
||||
}
|
||||
defer mindflowDB.Close()
|
||||
|
||||
if err := ctxi18n.LoadWithDefault(locales.Content, "en"); err != nil {
|
||||
log.Fatalln("Failed to load i18n:", err)
|
||||
}
|
||||
|
||||
hand := dwhttp.NewHandlers(*captchaExpiry, owner, *guestbookPageSize, guestbookDB, mindflowDB)
|
||||
|
||||
r := httpr.New()
|
||||
@ -101,7 +107,7 @@ func main() {
|
||||
s.Handler(http.MethodPatch, "/category/:id", mindflowApi.EditCategory)
|
||||
s.Handler(http.MethodDelete, "/category/:id", mindflowApi.DeleteCategory)
|
||||
|
||||
srv := dwhttp.NewHttpServer(r)
|
||||
srv := dwhttp.NewHttpServer(I18nMiddleware(r))
|
||||
|
||||
if err := srv.Start(*listenAddress); err != nil {
|
||||
log.Fatalln(err)
|
||||
@ -117,3 +123,13 @@ func main() {
|
||||
|
||||
<-doneSignal
|
||||
}
|
||||
|
||||
func I18nMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx, err := ctxi18n.WithLocale(r.Context(), r.Header.Get("Accept-Language"))
|
||||
if err != nil {
|
||||
log.Println("i18nmw:", err)
|
||||
}
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
})
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"math"
|
||||
"net/http"
|
||||
@ -36,15 +35,15 @@ func NewHandlers(captchaExpire time.Duration, owner string, gbPageSize int64,
|
||||
}
|
||||
|
||||
func (h *Handlers) Index(w http.ResponseWriter, r *http.Request) {
|
||||
web.Index(r).Render(context.Background(), w)
|
||||
web.Index(r).Render(r.Context(), w)
|
||||
}
|
||||
|
||||
func (h *Handlers) Privacy(w http.ResponseWriter, r *http.Request) {
|
||||
web.Privacy(r).Render(context.Background(), w)
|
||||
web.Privacy(r).Render(r.Context(), w)
|
||||
}
|
||||
|
||||
func (h *Handlers) Stuff(w http.ResponseWriter, r *http.Request) {
|
||||
web.Stuff(r).Render(context.Background(), w)
|
||||
web.Stuff(r).Render(r.Context(), w)
|
||||
}
|
||||
|
||||
func (h *Handlers) Mindflow(w http.ResponseWriter, r *http.Request) {
|
||||
@ -62,7 +61,7 @@ func (h *Handlers) Mindflow(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
web.Mindflow(posts, categories, r).Render(context.Background(), w)
|
||||
web.Mindflow(posts, categories, r).Render(r.Context(), w)
|
||||
}
|
||||
|
||||
func (h *Handlers) MindflowAdmin(w http.ResponseWriter, r *http.Request) {
|
||||
@ -78,7 +77,7 @@ func (h *Handlers) MindflowAdmin(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
web.MindflowAdmin(posts, categories, r).Render(context.Background(), w)
|
||||
web.MindflowAdmin(posts, categories, r).Render(r.Context(), w)
|
||||
}
|
||||
|
||||
func (h *Handlers) About(w http.ResponseWriter, r *http.Request) {
|
||||
@ -96,7 +95,7 @@ func (h *Handlers) About(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
web.About(&lst, r).Render(context.Background(), w)
|
||||
web.About(&lst, r).Render(r.Context(), w)
|
||||
}
|
||||
|
||||
func (h *Handlers) Article(w http.ResponseWriter, r *http.Request) {
|
||||
@ -107,7 +106,7 @@ func (h *Handlers) Article(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
web.Article(artcl.Title, artcl.Description, string(artcl.Body), name, artcl.Date, r).Render(context.Background(), w)
|
||||
web.Article(artcl.Title, artcl.Description, string(artcl.Body), name, artcl.Date, r).Render(r.Context(), w)
|
||||
}
|
||||
|
||||
func (h *Handlers) Guestbook(w http.ResponseWriter, r *http.Request) {
|
||||
@ -144,7 +143,7 @@ func (h *Handlers) Guestbook(w http.ResponseWriter, r *http.Request) {
|
||||
dwc := dwcaptcha.NewDwellingCaptcha(h.captchaExpire)
|
||||
_, id := inmemdb.New(r.RemoteAddr, dwc)
|
||||
|
||||
web.Guestbook(string(id), h.owner, entries, pageCount, page, r).Render(context.Background(), w)
|
||||
web.Guestbook(string(id), h.owner, entries, pageCount, page, r).Render(r.Context(), w)
|
||||
}
|
||||
|
||||
func (h *Handlers) GuestbookAdmin(w http.ResponseWriter, r *http.Request) {
|
||||
@ -158,7 +157,7 @@ func (h *Handlers) GuestbookAdmin(w http.ResponseWriter, r *http.Request) {
|
||||
entry.Message = strings.ReplaceAll(entry.Message, "\\n", "\n")
|
||||
}
|
||||
|
||||
web.GuestbookAdmin(h.owner, entries, r).Render(context.Background(), w)
|
||||
web.GuestbookAdmin(h.owner, entries, r).Render(r.Context(), w)
|
||||
}
|
||||
|
||||
func (h *Handlers) RSS(w http.ResponseWriter, r *http.Request) {
|
||||
@ -172,7 +171,7 @@ func (h *Handlers) RSS(w http.ResponseWriter, r *http.Request) {
|
||||
scheme = "http"
|
||||
}
|
||||
|
||||
web.RSS(scheme+"://"+r.Host, h.owner, posts, r).Render(context.Background(), w)
|
||||
web.RSS(scheme+"://"+r.Host, h.owner, posts, r).Render(r.Context(), w)
|
||||
}
|
||||
|
||||
func ServeAsset(path string) func(http.ResponseWriter, *http.Request) {
|
||||
@ -184,7 +183,7 @@ func ServeAsset(path string) func(http.ResponseWriter, *http.Request) {
|
||||
|
||||
func Error(w http.ResponseWriter, code int, reason, message string, r *http.Request) {
|
||||
w.WriteHeader(code)
|
||||
web.ErrorXXX(code, reason, message, r).Render(context.Background(), w)
|
||||
web.ErrorXXX(code, reason, message, r).Render(r.Context(), w)
|
||||
}
|
||||
|
||||
func cleanupNewlines(text string) (out string) {
|
||||
|
30
web/locales/en/en.yaml
Normal file
30
web/locales/en/en.yaml
Normal file
@ -0,0 +1,30 @@
|
||||
en:
|
||||
base:
|
||||
rss-feed: "RSS"
|
||||
rss-feed-title: "Stay up to date on what's going on."
|
||||
copy-author: "Alexander \"Arav\" Andreev"
|
||||
privacy-statements-link: "Privacy statements"
|
||||
menu:
|
||||
home: "Home"
|
||||
stuff: "Stuff"
|
||||
mindflow: "Mindflow"
|
||||
about: "About"
|
||||
guestbook: "Guestbook"
|
||||
privacy: "Privacy"
|
||||
article:
|
||||
go-back: "Back to a list"
|
||||
guestbook:
|
||||
description: "This is my guestbook. Welcome."
|
||||
form:
|
||||
name: "Name (Anonymous if left blank)"
|
||||
website: "Website (optional)"
|
||||
message: "Your message"
|
||||
hide-website: "Hide website <small>(only I can see if set)</small>"
|
||||
quote-usage: "Use > to make a quote."
|
||||
captcha-validity: "Valid for <b>10</b> minutes."
|
||||
send-post: "Send"
|
||||
post:
|
||||
by: "by"
|
||||
on: "on"
|
||||
reply: "Reply by"
|
||||
no-posts: "No posts."
|
9
web/locales/locales.go
Normal file
9
web/locales/locales.go
Normal file
@ -0,0 +1,9 @@
|
||||
package locales
|
||||
|
||||
import (
|
||||
"embed"
|
||||
)
|
||||
|
||||
//go:embed en
|
||||
//go:embed ru
|
||||
var Content embed.FS
|
31
web/locales/ru/ru.yaml
Normal file
31
web/locales/ru/ru.yaml
Normal file
@ -0,0 +1,31 @@
|
||||
ru:
|
||||
base:
|
||||
rss-feed: "RSS"
|
||||
rss-feed-title: "Будь в курсе происходящего."
|
||||
copy-author: "Александр «Arav» Андреев"
|
||||
privacy-statements-link: "О приватности"
|
||||
section:
|
||||
home: "Домой"
|
||||
stuff: "Всякое"
|
||||
mindflow: "Блог"
|
||||
about: "О..."
|
||||
guestbook: "Гостевая"
|
||||
privacy: "Приватность"
|
||||
article:
|
||||
go-back: "К списку"
|
||||
guestbook:
|
||||
description: "Моя гостевая. Добро пожаловать."
|
||||
form:
|
||||
name: "Имя (Аноним если оставить пустым)"
|
||||
website: "Вебсайт (необязательно)"
|
||||
message: "Твоё сообщение"
|
||||
hide-website-1: "Скрыть вебсайт"
|
||||
hide-website-2: "(будет видно только мне)"
|
||||
quote-usage: "Используй > для цитаты."
|
||||
captcha-validity: "Действительна <b>10</b> минут."
|
||||
send-post: "Отправить"
|
||||
post:
|
||||
by: "от"
|
||||
on: " "
|
||||
reply: "Ответ"
|
||||
no-posts: "Нет постов."
|
Loading…
Reference in New Issue
Block a user