summaryrefslogtreecommitdiffci
path: root/internal/router
diff options
from:
to:
context:
space:
mode:
authorGravatar SayaAndy <saya.andy@posteo.com> 2026-05-17 17:13:32 +0700
committerGravatar SayaAndy <saya.andy@posteo.com> 2026-05-17 17:13:32 +0700
commite9353a66bf51486f702eaa0f591dea54c9bd4cd1 (patch)
treedd8d121366259045799475f4e402f2908af1d997 /internal/router
parent1c441f5eab9a2a24fe5309178ce010f32adac1c7 (diff)
downloadweb-e9353a66bf51486f702eaa0f591dea54c9bd4cd1.tar.gz
web-e9353a66bf51486f702eaa0f591dea54c9bd4cd1.zip
refactor: rewrite localization for dynamic set and get
feat: medley localnames feat: integrate package minor updates fix: on errors with blog client init write correct type
Diffstat (limited to 'internal/router')
-rw-r--r--internal/router/handlers/api-v1-email-is-in-verification.go3
-rw-r--r--internal/router/handlers/api-v1-email-send-verification-code.go15
-rw-r--r--internal/router/handlers/api-v1-email-verify.go7
-rw-r--r--internal/router/handlers/api-v1-subs-put.go7
-rw-r--r--internal/router/handlers/lang-blog.go9
-rw-r--r--internal/router/handlers/lang-user-unsubscribe.go9
-rw-r--r--internal/router/handlers/lang-user.go9
-rw-r--r--internal/router/handlers/lang.go9
-rw-r--r--internal/router/router.go18
9 files changed, 40 insertions, 46 deletions
diff --git a/internal/router/handlers/api-v1-email-is-in-verification.go b/internal/router/handlers/api-v1-email-is-in-verification.go
index 4f05f48..b8ae162 100644
--- a/internal/router/handlers/api-v1-email-is-in-verification.go
+++ b/internal/router/handlers/api-v1-email-is-in-verification.go
@@ -6,6 +6,7 @@ import (
"strings"
"github.com/SayaAndy/saya-today-web/internal/router"
+ "github.com/SayaAndy/saya-today-web/l10n"
"github.com/gofiber/fiber/v2"
)
@@ -49,7 +50,7 @@ func (r *OngoingVerificationHandler) Render(c *fiber.Ctx, supplements *router.Su
if !isAllowed {
sterileDataset["striked-end-time"] = template.HTMLAttr(fmt.Sprintf("data-striked-end-time=\"%d\"", whenAllowed.UnixMilli()))
templateMap["Status"] = "Neutral"
- templateMap["Message"] = strings.ReplaceAll(supplements.Localization[lang].UserProfile.DelayTilVerification, "{}", whenAllowed.Format("2006-01-02 15:04:05 MST"))
+ templateMap["Message"] = strings.ReplaceAll(l10n.T.GetPath(lang, "UserProfile", "DelayTilVerification").(string), "{}", whenAllowed.Format("2006-01-02 15:04:05 MST"))
} else {
templateMap["Status"] = "OK"
templateMap["Message"] = ""
diff --git a/internal/router/handlers/api-v1-email-send-verification-code.go b/internal/router/handlers/api-v1-email-send-verification-code.go
index 0b53efa..ea8df4d 100644
--- a/internal/router/handlers/api-v1-email-send-verification-code.go
+++ b/internal/router/handlers/api-v1-email-send-verification-code.go
@@ -7,6 +7,7 @@ import (
"strings"
"github.com/SayaAndy/saya-today-web/internal/router"
+ "github.com/SayaAndy/saya-today-web/l10n"
"github.com/gofiber/fiber/v2"
)
@@ -49,27 +50,27 @@ func (r *SendVerificationCodeHandler) Render(c *fiber.Ctx, supplements *router.S
email := c.FormValue("email")
if email == "" {
templateMap["Status"] = "Failed"
- templateMap["Message"] = supplements.Localization[lang].UserProfile.EmailEmpty
+ templateMap["Message"] = l10n.T.GetPath(lang, "UserProfile", "EmailEmpty").(string)
return fiber.StatusUnprocessableEntity, nil
}
isTaken, err := supplements.Mailer.MailIsTaken(email)
if err != nil {
templateMap["Status"] = "Failed"
- templateMap["Message"] = supplements.Localization[lang].UserProfile.VerificationCodeSendingError
+ templateMap["Message"] = l10n.T.GetPath(lang, "UserProfile", "VerificationCodeSendingError").(string)
slog.Error("failed to check if address is already taken", slog.String("error", err.Error()))
return fiber.StatusUnprocessableEntity, nil
}
if isTaken {
templateMap["Status"] = "Failed"
- templateMap["Message"] = supplements.Localization[lang].UserProfile.EmailTaken
+ templateMap["Message"] = l10n.T.GetPath(lang, "UserProfile", "EmailTaken").(string)
return fiber.StatusUnprocessableEntity, nil
}
if isAllowed, whenAllowed, _ := supplements.Mailer.IsAllowedToRetryVerification(id); !isAllowed {
templateMap["Status"] = "Failed"
- templateMap["Message"] = strings.ReplaceAll(supplements.Localization[lang].UserProfile.DelayTilVerification, "{}", whenAllowed.Format("2006-01-02 15:04:05 MST"))
+ templateMap["Message"] = strings.ReplaceAll(l10n.T.GetPath(lang, "UserProfile", "DelayTilVerification").(string), "{}", whenAllowed.Format("2006-01-02 15:04:05 MST"))
templateMap["DataAttributes"] = map[string]any{
"striked-end-time": template.HTMLAttr(fmt.Sprintf("data-striked-end-time=\"%d\"", whenAllowed.UnixMilli())),
}
@@ -78,20 +79,20 @@ func (r *SendVerificationCodeHandler) Render(c *fiber.Ctx, supplements *router.S
if previousEmail, _, _ := supplements.Mailer.GetInfo(supplements.Mailer.GetHash(id)); previousEmail == email {
templateMap["Status"] = "Failed"
- templateMap["Message"] = supplements.Localization[lang].UserProfile.EmailAlreadyValidated
+ templateMap["Message"] = l10n.T.GetPath(lang, "UserProfile", "EmailAlreadyValidated").(string)
return fiber.StatusUnprocessableEntity, nil
}
if err = supplements.Mailer.SendVerificationCode(id, email, lang); err != nil {
templateMap["Status"] = "Failed"
- templateMap["Message"] = supplements.Localization[lang].UserProfile.VerificationCodeSendingError
+ templateMap["Message"] = l10n.T.GetPath(lang, "UserProfile", "VerificationCodeSendingError").(string)
slog.Error("failed to send a verification code", slog.String("error", err.Error()))
return fiber.StatusUnprocessableEntity, nil
}
_, endTime, codeExpiry := supplements.Mailer.IsAllowedToRetryVerification(id)
templateMap["Status"] = "OK"
- templateMap["Message"] = supplements.Localization[lang].UserProfile.VerificationCodeSent
+ templateMap["Message"] = l10n.T.GetPath(lang, "UserProfile", "VerificationCodeSent").(string)
templateMap["DataAttributes"] = map[string]any{
"striked-end-time": template.HTMLAttr(fmt.Sprintf("data-striked-end-time=\"%d\"", endTime.UnixMilli())),
"code-expiry-time": template.HTMLAttr(fmt.Sprintf("data-code-expiry-time=\"%d\"", codeExpiry.UnixMilli())),
diff --git a/internal/router/handlers/api-v1-email-verify.go b/internal/router/handlers/api-v1-email-verify.go
index ace1870..65ad6d9 100644
--- a/internal/router/handlers/api-v1-email-verify.go
+++ b/internal/router/handlers/api-v1-email-verify.go
@@ -5,6 +5,7 @@ import (
"log/slog"
"github.com/SayaAndy/saya-today-web/internal/router"
+ "github.com/SayaAndy/saya-today-web/l10n"
"github.com/gofiber/fiber/v2"
)
@@ -46,19 +47,19 @@ func (r *VerifyCodeHandler) Render(c *fiber.Ctx, supplements *router.Supplements
if verificationCode == "" {
templateMap["Status"] = "Failed"
- templateMap["Message"] = supplements.Localization[lang].UserProfile.VerificationEmpty
+ templateMap["Message"] = l10n.T.GetPath(lang, "UserProfile", "VerificationEmpty").(string)
return fiber.StatusUnprocessableEntity, nil
}
if err = supplements.Mailer.Verify(verificationCode, lang); err != nil {
slog.Warn("verification code is invalid", slog.String("verification_code", verificationCode), slog.String("error", err.Error()))
templateMap["Status"] = "Failed"
- templateMap["Message"] = supplements.Localization[lang].UserProfile.VerificationFailed
+ templateMap["Message"] = l10n.T.GetPath(lang, "UserProfile", "VerificationFailed").(string)
return fiber.StatusUnprocessableEntity, nil
}
templateMap["Status"] = "OK"
- templateMap["Message"] = supplements.Localization[lang].UserProfile.VerificationSuccess
+ templateMap["Message"] = l10n.T.GetPath(lang, "UserProfile", "VerificationSuccess").(string)
templateMap["DataAttributes"] = map[string]any{
"hide-verification-panel": template.HTMLAttr("data-code-expiry-time=\"true\""),
}
diff --git a/internal/router/handlers/api-v1-subs-put.go b/internal/router/handlers/api-v1-subs-put.go
index 32fba7e..12dc5cf 100644
--- a/internal/router/handlers/api-v1-subs-put.go
+++ b/internal/router/handlers/api-v1-subs-put.go
@@ -3,6 +3,7 @@ package handlers
import (
"github.com/SayaAndy/saya-today-web/internal/mailer"
"github.com/SayaAndy/saya-today-web/internal/router"
+ "github.com/SayaAndy/saya-today-web/l10n"
"github.com/gofiber/fiber/v2"
)
@@ -52,18 +53,18 @@ func (r *PutSubsHandler) Render(c *fiber.Ctx, supplements *router.Supplements, l
subscriptionTypeEnum = mailer.Specific
default:
templateMap["Status"] = "Failed"
- templateMap["Message"] = supplements.Localization[lang].UserProfile.SubscribeInvalidType
+ templateMap["Message"] = l10n.T.GetPath(lang, "UserProfile", "SubscribeInvalidType").(string)
return fiber.StatusUnprocessableEntity, nil
}
specificTags := c.FormValue("tags_picked")
if err = supplements.Mailer.Subscribe(supplements.Mailer.GetHash(c.IP()), subscriptionTypeEnum, specificTags); err != nil {
templateMap["Status"] = "Failed"
- templateMap["Message"] = supplements.Localization[lang].UserProfile.FailedToSubscribe
+ templateMap["Message"] = l10n.T.GetPath(lang, "UserProfile", "FailedToSubscribe").(string)
return fiber.StatusUnprocessableEntity, nil
}
templateMap["Status"] = "OK"
- templateMap["Message"] = supplements.Localization[lang].UserProfile.SubscribedSuccessfully
+ templateMap["Message"] = l10n.T.GetPath(lang, "UserProfile", "SubscribedSuccessfully").(string)
return fiber.StatusOK, nil
}
diff --git a/internal/router/handlers/lang-blog.go b/internal/router/handlers/lang-blog.go
index 9f7947b..c31c2eb 100644
--- a/internal/router/handlers/lang-blog.go
+++ b/internal/router/handlers/lang-blog.go
@@ -11,6 +11,7 @@ import (
"github.com/SayaAndy/saya-today-web/internal/blog"
"github.com/SayaAndy/saya-today-web/internal/router"
+ "github.com/SayaAndy/saya-today-web/l10n"
"github.com/gofiber/fiber/v2"
)
@@ -57,8 +58,8 @@ func (r *CatalogueHandler) SitemapInfo(supplements *router.Supplements) []router
func (r *CatalogueHandler) AddMeta(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (meta []router.MetaField, err error) {
return []router.MetaField{
- {Property: "og:title", Content: supplements.Localization[lang].BlogSearch.Header},
- {Property: "og:description", Content: supplements.Localization[lang].BlogSearch.Description},
+ {Property: "og:title", Content: l10n.T.GetPath(lang, "BlogSearch", "Header").(string)},
+ {Property: "og:description", Content: l10n.T.GetPath(lang, "BlogSearch", "Description").(string)},
{Property: "og:url", Content: fmt.Sprintf("%s/%s/blog", templateMap["CanonicalEndpoint"], lang)},
{Property: "og:type", Content: "website"},
}, nil
@@ -85,14 +86,14 @@ func (r *CatalogueHandler) RenderBody(c *fiber.Ctx, supplements *router.Suppleme
templateMap["Tags"] = tagsArray
templateMap["QuerySort"] = querySort
templateMap["QueryTags"] = strings.Join(queryTags, ",")
- templateMap["Title"] = supplements.Localization[lang].BlogSearch.Header
+ templateMap["Title"] = l10n.T.GetPath(lang, "BlogSearch", "Header").(string)
templateMap["PreviousBlogPage"] = previousBlogPage
return fiber.StatusOK, nil
}
func (r *CatalogueHandler) RenderHeader(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) {
- templateMap["Title"] = supplements.Localization[lang].BlogSearch.Header
+ templateMap["Title"] = l10n.T.GetPath(lang, "BlogSearch", "Header").(string)
return fiber.StatusOK, nil
}
diff --git a/internal/router/handlers/lang-user-unsubscribe.go b/internal/router/handlers/lang-user-unsubscribe.go
index 4fbd244..e22d854 100644
--- a/internal/router/handlers/lang-user-unsubscribe.go
+++ b/internal/router/handlers/lang-user-unsubscribe.go
@@ -4,6 +4,7 @@ import (
"log/slog"
"github.com/SayaAndy/saya-today-web/internal/router"
+ "github.com/SayaAndy/saya-today-web/l10n"
"github.com/gofiber/fiber/v2"
)
@@ -39,24 +40,24 @@ func (r *UnsubscribeHandler) Render(c *fiber.Ctx, supplements *router.Supplement
if unsubscribeCode == "" {
statusColor = "0, 0, 255"
statusEmoji = "(╭ರ_•́)"
- statusText = supplements.Localization[lang].UnsubscribePage.UnsetCode
+ statusText = l10n.T.GetPath(lang, "UnsubscribePage", "UnsetCode").(string)
status = fiber.ErrBadRequest.Code
} else if clientError, serverError := supplements.Mailer.Unsubscribe(unsubscribeCode); clientError != nil {
slog.Info("got a client error when unsubscribing", slog.String("error", clientError.Error()))
statusColor = "255, 0, 0"
statusEmoji = "(͠≖~≖ ͡ )"
- statusText = supplements.Localization[lang].UnsubscribePage.InvalidCode
+ statusText = l10n.T.GetPath(lang, "UnsubscribePage", "InvalidCode").(string)
status = fiber.ErrBadRequest.Code
} else if serverError != nil {
slog.Error("got a server error when unsubscribing", slog.String("error", serverError.Error()))
statusColor = "255, 128, 0"
statusEmoji = "( ˶°ㅁ°) !!"
- statusText = supplements.Localization[lang].UnsubscribePage.OnServerError
+ statusText = l10n.T.GetPath(lang, "UnsubscribePage", "OnServerError").(string)
status = fiber.ErrInternalServerError.Code
} else {
statusColor = "0, 255, 0"
statusEmoji = "♡⸜(˶˃ ᵕ ˂˶)⸝♡"
- statusText = supplements.Localization[lang].UnsubscribePage.Success
+ statusText = l10n.T.GetPath(lang, "UnsubscribePage", "Success").(string)
status = fiber.StatusOK
}
diff --git a/internal/router/handlers/lang-user.go b/internal/router/handlers/lang-user.go
index 0dda529..085a9aa 100644
--- a/internal/router/handlers/lang-user.go
+++ b/internal/router/handlers/lang-user.go
@@ -6,6 +6,7 @@ import (
"github.com/SayaAndy/saya-today-web/internal/mailer"
"github.com/SayaAndy/saya-today-web/internal/router"
+ "github.com/SayaAndy/saya-today-web/l10n"
"github.com/gofiber/fiber/v2"
)
@@ -40,15 +41,15 @@ func (r *UserHandler) ToValidateLang() router.LangSetting {
func (r *UserHandler) AddMeta(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (meta []router.MetaField, err error) {
return []router.MetaField{
{Name: "robots", Content: "noindex,nofollow"},
- {Property: "og:title", Content: supplements.Localization[lang].UserProfile.Header},
- {Property: "og:description", Content: supplements.Localization[lang].UserProfile.Description},
+ {Property: "og:title", Content: l10n.T.GetPath(lang, "UserProfile", "Header").(string)},
+ {Property: "og:description", Content: l10n.T.GetPath(lang, "UserProfile", "Description").(string)},
{Property: "og:url", Content: fmt.Sprintf("%s/%s/user", templateMap["CanonicalEndpoint"], lang)},
{Property: "og:type", Content: "website"},
}, nil
}
func (r *UserHandler) RenderBody(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) {
- templateMap["Title"] = supplements.Localization[lang].UserProfile.Header
+ templateMap["Title"] = l10n.T.GetPath(lang, "UserProfile", "Header").(string)
email, _, err := supplements.Mailer.GetInfo(supplements.Mailer.GetHash(c.IP()))
if err != nil {
@@ -83,6 +84,6 @@ func (r *UserHandler) RenderBody(c *fiber.Ctx, supplements *router.Supplements,
}
func (r *UserHandler) RenderHeader(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) {
- templateMap["Title"] = supplements.Localization[lang].UserProfile.Header
+ templateMap["Title"] = l10n.T.GetPath(lang, "UserProfile", "Header").(string)
return fiber.StatusOK, nil
}
diff --git a/internal/router/handlers/lang.go b/internal/router/handlers/lang.go
index 25b5036..cc0b33b 100644
--- a/internal/router/handlers/lang.go
+++ b/internal/router/handlers/lang.go
@@ -6,6 +6,7 @@ import (
"time"
"github.com/SayaAndy/saya-today-web/internal/router"
+ "github.com/SayaAndy/saya-today-web/l10n"
"github.com/gofiber/fiber/v2"
)
@@ -51,8 +52,8 @@ func (r *HomeHandler) SitemapInfo(supplements *router.Supplements) []router.Site
func (r *HomeHandler) AddMeta(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (meta []router.MetaField, err error) {
return []router.MetaField{
- {Property: "og:title", Content: supplements.Localization[lang].HomePage.Header},
- {Property: "og:description", Content: supplements.Localization[lang].HomePage.HomePageDescription},
+ {Property: "og:title", Content: l10n.T.GetPath(lang, "HomePage", "Header").(string)},
+ {Property: "og:description", Content: l10n.T.GetPath(lang, "HomePage", "HomePageDescription").(string)},
{Property: "og:image", Content: fmt.Sprintf(
supplements.PhotoStorage.HomePageGifs.BaseUrl,
supplements.PhotoStorage.HomePageGifs.Indexes[rand.Int()%len(supplements.PhotoStorage.HomePageGifs.Indexes)],
@@ -63,7 +64,7 @@ func (r *HomeHandler) AddMeta(c *fiber.Ctx, supplements *router.Supplements, lan
}
func (r *HomeHandler) RenderBody(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) {
- templateMap["Title"] = supplements.Localization[lang].HomePage.Header
+ templateMap["Title"] = l10n.T.GetPath(lang, "HomePage", "Header").(string)
templateMap["FilledHeartCount"] = uint(40)
templateMap["OutlineHeartCount"] = uint(40)
templateMap["GifUrl"] = fmt.Sprintf(
@@ -75,6 +76,6 @@ func (r *HomeHandler) RenderBody(c *fiber.Ctx, supplements *router.Supplements,
}
func (r *HomeHandler) RenderHeader(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) {
- templateMap["Title"] = supplements.Localization[lang].HomePage.Header
+ templateMap["Title"] = l10n.T.GetPath(lang, "HomePage", "Header").(string)
return fiber.StatusOK, nil
}
diff --git a/internal/router/router.go b/internal/router/router.go
index a1208e0..43d6138 100644
--- a/internal/router/router.go
+++ b/internal/router/router.go
@@ -23,7 +23,6 @@ import (
"github.com/SayaAndy/saya-today-web/internal/mailer"
"github.com/SayaAndy/saya-today-web/internal/tailwind"
"github.com/SayaAndy/saya-today-web/internal/templatemanager"
- "github.com/SayaAndy/saya-today-web/locale"
"github.com/dgraph-io/ristretto/v2"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/compress"
@@ -95,7 +94,6 @@ type Route interface {
type Supplements struct {
DB *sql.DB
BlogClient blog.Client
- Localization map[string]*locale.LocaleConfig
AvailableLanguages []config.AvailableLanguageConfig
ClientCache *ClientCache
PageCache *ristretto.Cache[string, []byte]
@@ -149,16 +147,7 @@ func NewRouter(cfg *config.Config) (*Router, error) {
supplements.BlogClient, err = blog.NewClientMap[cfg.BlogPages.Storage.Type](&cfg.BlogPages.Storage)
if err != nil {
- return nil, fmt.Errorf("fail to initialize b2 client: %w", err)
- }
-
- supplements.Localization = make(map[string]*locale.LocaleConfig, len(cfg.AvailableLanguages))
- for _, lang := range cfg.AvailableLanguages {
- localeCfg, err := locale.InitConfig(cfg.LocalePath + lang.LocFile)
- if err != nil {
- return nil, fmt.Errorf("fail to initialize a locale: %w", err)
- }
- supplements.Localization[lang.Name] = localeCfg
+ return nil, fmt.Errorf("fail to initialize blog client: type %s: %w", cfg.BlogPages.Storage.Type, err)
}
supplements.MarkdownRenderer = goldmark.New(
@@ -200,7 +189,7 @@ func NewRouter(cfg *config.Config) (*Router, error) {
}
supplements.Mailer, err = mailer.NewMailer(supplements.DB, cfg.Mail.ClientHost, cfg.Mail.MailHost,
- cfg.Mail.PublicName, cfg.Mail.MailAddress, cfg.Mail.Username, cfg.Mail.Password, []byte(cfg.Mail.Salt), supplements.Localization)
+ cfg.Mail.PublicName, cfg.Mail.MailAddress, cfg.Mail.Username, cfg.Mail.Password, []byte(cfg.Mail.Salt))
if err != nil {
return nil, fmt.Errorf("fail to initialize mailer: %w", err)
}
@@ -314,7 +303,6 @@ func (r *Router) InitRoutes() (err error) {
}
defaultMap := fiber.Map{
- "L": r.supplements.Localization[lang],
"Lang": lang,
"Path": trimmedPath,
"QueryString": queryString,
@@ -467,7 +455,6 @@ func (r *Router) generalPage(c *fiber.Ctx, route Route, lang string) error {
}
valueMap := fiber.Map{
- "L": r.supplements.Localization[lang],
"Lang": lang,
"Path": trimmedPath,
"QueryString": queryString,
@@ -593,7 +580,6 @@ func (r *Router) generalPageSegment(c *fiber.Ctx, part string) error {
var statusCode int
defaultMap := fiber.Map{
- "L": r.supplements.Localization[lang],
"Lang": lang,
"Path": strings.Trim(path, "/"),
"QueryString": queryString,