Diffstat (limited to 'internal')
| -rw-r--r-- | internal/blog/b2.go | 21 | ||||
| -rw-r--r-- | internal/blog/client.go | 1 | ||||
| -rw-r--r-- | internal/blog/index.go | 5 | ||||
| -rw-r--r-- | internal/blog/s3.go | 24 | ||||
| -rw-r--r-- | internal/mailer/mailer.go | 16 | ||||
| -rw-r--r-- | internal/router/handlers/api-v1-email-is-in-verification.go | 3 | ||||
| -rw-r--r-- | internal/router/handlers/api-v1-email-send-verification-code.go | 15 | ||||
| -rw-r--r-- | internal/router/handlers/api-v1-email-verify.go | 7 | ||||
| -rw-r--r-- | internal/router/handlers/api-v1-subs-put.go | 7 | ||||
| -rw-r--r-- | internal/router/handlers/lang-blog.go | 9 | ||||
| -rw-r--r-- | internal/router/handlers/lang-user-unsubscribe.go | 9 | ||||
| -rw-r--r-- | internal/router/handlers/lang-user.go | 9 | ||||
| -rw-r--r-- | internal/router/handlers/lang.go | 9 | ||||
| -rw-r--r-- | internal/router/router.go | 18 | ||||
| -rw-r--r-- | internal/templatemanager/templatemanager.go | 5 |
15 files changed, 61 insertions, 97 deletions
diff --git a/internal/blog/b2.go b/internal/blog/b2.go index f2ac890..8a4d363 100644 --- a/internal/blog/b2.go +++ b/internal/blog/b2.go @@ -2,7 +2,6 @@ package blog import ( "context" - "encoding/json" "fmt" "slices" "strings" @@ -38,20 +37,6 @@ func NewB2Client(cfg *config.StorageConfig) (Client, error) { return &B2Client{b2cl: b2cl, bucket: bucket, prefix: b2cfg.Prefix}, nil } -func (c *B2Client) GetMedleys() ([]MedleyEntry, error) { - idxRaw, err := c.readAll(MedleysIndexFileName) - if err != nil { - return nil, fmt.Errorf("read %s: %w", MedleysIndexFileName, err) - } - - var idx []MedleyEntry - if err := json.Unmarshal(idxRaw, &idx); err != nil { - return nil, fmt.Errorf("unmarshal %s: %w", MedleysIndexFileName, err) - } - - return idx, nil -} - func (c *B2Client) Scan(prefix string) ([]*Page, error) { filePaths := []*Page{} @@ -117,11 +102,7 @@ func (c *B2Client) Scan(prefix string) ([]*Page, error) { } func (c *B2Client) ReadAll(path string) ([]byte, error) { - return c.readAll(c.prefix + path) -} - -func (c *B2Client) readAll(path string) ([]byte, error) { - obj := c.bucket.Object(path) + obj := c.bucket.Object(c.prefix + path) if obj == nil { return nil, fmt.Errorf("failed to reference object in B2 bucket") } diff --git a/internal/blog/client.go b/internal/blog/client.go index 53eb0fd..56bbee4 100644 --- a/internal/blog/client.go +++ b/internal/blog/client.go @@ -17,7 +17,6 @@ type Page struct { type Client interface { Scan(prefix string) ([]*Page, error) - GetMedleys() ([]MedleyEntry, error) ReadAll(path string) ([]byte, error) ReadFrontmatter(path string) (metadata *frontmatter.Metadata, markdown []byte, err error) } diff --git a/internal/blog/index.go b/internal/blog/index.go index a09b59e..6c1a560 100644 --- a/internal/blog/index.go +++ b/internal/blog/index.go @@ -92,9 +92,8 @@ func (idx *Index) UnmarshalJSON(data []byte) error { } type MedleyEntry struct { - Codename string `json:"codename"` - Localnames map[string]string `json:"localnames"` - Content []string `json:"content"` + Codename string `json:"codename"` + Content []string `json:"content"` } type MedleyPageEntry struct { diff --git a/internal/blog/s3.go b/internal/blog/s3.go index 3c1a932..04fad33 100644 --- a/internal/blog/s3.go +++ b/internal/blog/s3.go @@ -10,13 +10,14 @@ import ( "github.com/SayaAndy/saya-today-web/config" "github.com/SayaAndy/saya-today-web/internal/frontmatter" - "github.com/SayaAndy/saya-today-web/l10n" "github.com/aws/aws-sdk-go-v2/aws" awsconfig "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/s3" ) +const s3ScanConcurrency = 32 + type S3Client struct { prefix string bucketName string @@ -59,20 +60,6 @@ func NewS3Client(cfg *config.StorageConfig) (Client, error) { return &S3Client{s3cfg.Prefix, s3cfg.BucketName, s3cl}, nil } -func (c *S3Client) GetMedleys() ([]MedleyEntry, error) { - idxRaw, err := c.readAll(MedleysIndexFileName) - if err != nil { - return nil, fmt.Errorf("read %s: %w", MedleysIndexFileName, err) - } - - var idx []MedleyEntry - if err := json.Unmarshal(idxRaw, &idx); err != nil { - return nil, fmt.Errorf("unmarshal %s: %w", MedleysIndexFileName, err) - } - - return idx, nil -} - func (c *S3Client) Scan(prefix string) ([]*Page, error) { out, err := c.s3cl.GetObject(context.Background(), &s3.GetObjectInput{ Bucket: aws.String(c.bucketName), @@ -169,13 +156,6 @@ func (c *S3Client) Scan(prefix string) ([]*Page, error) { } } - medleys, _ := c.GetMedleys() - for _, medley := range medleys { - for locale, localname := range medley.Localnames { - l10n.T.SetPath(localname, true, locale, "Medleys", medley.Codename) - } - } - return pages, nil } diff --git a/internal/mailer/mailer.go b/internal/mailer/mailer.go index 33db4f7..ffa7b30 100644 --- a/internal/mailer/mailer.go +++ b/internal/mailer/mailer.go @@ -16,7 +16,7 @@ import ( "github.com/SayaAndy/saya-today-web/internal/blog" "github.com/SayaAndy/saya-today-web/internal/templatemanager" - "github.com/SayaAndy/saya-today-web/l10n" + "github.com/SayaAndy/saya-today-web/locale" "github.com/dgraph-io/ristretto/v2" "github.com/gofiber/fiber/v2" "github.com/wneessen/go-mail" @@ -43,6 +43,8 @@ type Mailer struct { hashMap map[string][]byte hashMapMutex sync.RWMutex + + l map[string]*locale.LocaleConfig } type SubscriptionType int @@ -53,7 +55,7 @@ const ( Specific ) -func NewMailer(db *sql.DB, clientHost string, mailHost string, publicName string, mailAddress string, username string, password string, salt []byte) (*Mailer, error) { +func NewMailer(db *sql.DB, clientHost string, mailHost string, publicName string, mailAddress string, username string, password string, salt []byte, localization map[string]*locale.LocaleConfig) (*Mailer, error) { verificationCodes, err := ristretto.NewCache(&ristretto.Config[uint64, string]{ NumCounters: 10000, MaxCost: 1 << 20, // 1 MB @@ -109,7 +111,7 @@ func NewMailer(db *sql.DB, clientHost string, mailHost string, publicName string End time.Time CodeExpiry time.Time }, 0), - }, nil + l: localization}, nil } func (m *Mailer) GetHash(id string) []byte { @@ -259,9 +261,10 @@ func (m *Mailer) SendVerificationCode(userId string, address string, lang string verificationInfo := fmt.Sprintf("%s.%s", base64.RawStdEncoding.EncodeToString([]byte(userId)), base64.RawStdEncoding.EncodeToString([]byte(address))) m.verificationCodes.Set(verificationCode, verificationInfo, int64(len(verificationInfo)+8)) - message.Subject(l10n.T.GetPath(lang, "Mail", "VerifyEmail", "Subject").(string)) + message.Subject(m.l[lang].Mail.VerifyEmail.Subject) msg, err := m.tm.Render("verify-email", fiber.Map{ + "L": m.l[lang], "Lang": lang, "VerificationCode": fmt.Sprintf("%X", verificationCode), "ClientHost": m.clientHost, @@ -496,10 +499,11 @@ rowLoop: rand.Read(unsubscribeCodeBytes) unsubscribeCode := binary.LittleEndian.Uint64(unsubscribeCodeBytes) - unsubscribeFooter := strings.Replace(l10n.T.GetPath(post.Lang, "Mail", "UnsubscribeFooter").(string), "{}", fmt.Sprintf(`<a style="color: #273de1 !important;" href="https://%s/%s/user/unsubscribe?code=%X">`, m.clientHost, post.Lang, unsubscribeCode), 1) + unsubscribeFooter := strings.Replace(m.l[post.Lang].Mail.UnsubscribeFooter, "{}", fmt.Sprintf(`<a style="color: #273de1 !important;" href="https://%s/%s/user/unsubscribe?code=%X">`, m.clientHost, post.Lang, unsubscribeCode), 1) unsubscribeFooter = strings.Replace(unsubscribeFooter, "{/}", "</a>", 1) msgBody, err := m.tm.Render("new-post", fiber.Map{ + "L": m.l[post.Lang], "Lang": post.Lang, "Post": post, "ClientHost": m.clientHost, @@ -525,7 +529,7 @@ rowLoop: message.SetMessageID() message.SetDate() message.SetBulk() - message.Subject(l10n.T.GetPath(post.Lang, "Mail", "NewPost", "Subject").(string)) + message.Subject(m.l[post.Lang].Mail.NewPost.Subject) message.SetBodyString(mail.TypeTextHTML, string(msgBody)) m.unsubscribeCodes.Set(unsubscribeCode, user.userId, 40) 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 b8ae162..4f05f48 100644 --- a/internal/router/handlers/api-v1-email-is-in-verification.go +++ b/internal/router/handlers/api-v1-email-is-in-verification.go @@ -6,7 +6,6 @@ import ( "strings" "github.com/SayaAndy/saya-today-web/internal/router" - "github.com/SayaAndy/saya-today-web/l10n" "github.com/gofiber/fiber/v2" ) @@ -50,7 +49,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(l10n.T.GetPath(lang, "UserProfile", "DelayTilVerification").(string), "{}", whenAllowed.Format("2006-01-02 15:04:05 MST")) + templateMap["Message"] = strings.ReplaceAll(supplements.Localization[lang].UserProfile.DelayTilVerification, "{}", 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 ea8df4d..0b53efa 100644 --- a/internal/router/handlers/api-v1-email-send-verification-code.go +++ b/internal/router/handlers/api-v1-email-send-verification-code.go @@ -7,7 +7,6 @@ import ( "strings" "github.com/SayaAndy/saya-today-web/internal/router" - "github.com/SayaAndy/saya-today-web/l10n" "github.com/gofiber/fiber/v2" ) @@ -50,27 +49,27 @@ func (r *SendVerificationCodeHandler) Render(c *fiber.Ctx, supplements *router.S email := c.FormValue("email") if email == "" { templateMap["Status"] = "Failed" - templateMap["Message"] = l10n.T.GetPath(lang, "UserProfile", "EmailEmpty").(string) + templateMap["Message"] = supplements.Localization[lang].UserProfile.EmailEmpty return fiber.StatusUnprocessableEntity, nil } isTaken, err := supplements.Mailer.MailIsTaken(email) if err != nil { templateMap["Status"] = "Failed" - templateMap["Message"] = l10n.T.GetPath(lang, "UserProfile", "VerificationCodeSendingError").(string) + templateMap["Message"] = supplements.Localization[lang].UserProfile.VerificationCodeSendingError 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"] = l10n.T.GetPath(lang, "UserProfile", "EmailTaken").(string) + templateMap["Message"] = supplements.Localization[lang].UserProfile.EmailTaken return fiber.StatusUnprocessableEntity, nil } if isAllowed, whenAllowed, _ := supplements.Mailer.IsAllowedToRetryVerification(id); !isAllowed { templateMap["Status"] = "Failed" - templateMap["Message"] = strings.ReplaceAll(l10n.T.GetPath(lang, "UserProfile", "DelayTilVerification").(string), "{}", whenAllowed.Format("2006-01-02 15:04:05 MST")) + templateMap["Message"] = strings.ReplaceAll(supplements.Localization[lang].UserProfile.DelayTilVerification, "{}", 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())), } @@ -79,20 +78,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"] = l10n.T.GetPath(lang, "UserProfile", "EmailAlreadyValidated").(string) + templateMap["Message"] = supplements.Localization[lang].UserProfile.EmailAlreadyValidated return fiber.StatusUnprocessableEntity, nil } if err = supplements.Mailer.SendVerificationCode(id, email, lang); err != nil { templateMap["Status"] = "Failed" - templateMap["Message"] = l10n.T.GetPath(lang, "UserProfile", "VerificationCodeSendingError").(string) + templateMap["Message"] = supplements.Localization[lang].UserProfile.VerificationCodeSendingError 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"] = l10n.T.GetPath(lang, "UserProfile", "VerificationCodeSent").(string) + templateMap["Message"] = supplements.Localization[lang].UserProfile.VerificationCodeSent 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 65ad6d9..ace1870 100644 --- a/internal/router/handlers/api-v1-email-verify.go +++ b/internal/router/handlers/api-v1-email-verify.go @@ -5,7 +5,6 @@ import ( "log/slog" "github.com/SayaAndy/saya-today-web/internal/router" - "github.com/SayaAndy/saya-today-web/l10n" "github.com/gofiber/fiber/v2" ) @@ -47,19 +46,19 @@ func (r *VerifyCodeHandler) Render(c *fiber.Ctx, supplements *router.Supplements if verificationCode == "" { templateMap["Status"] = "Failed" - templateMap["Message"] = l10n.T.GetPath(lang, "UserProfile", "VerificationEmpty").(string) + templateMap["Message"] = supplements.Localization[lang].UserProfile.VerificationEmpty 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"] = l10n.T.GetPath(lang, "UserProfile", "VerificationFailed").(string) + templateMap["Message"] = supplements.Localization[lang].UserProfile.VerificationFailed return fiber.StatusUnprocessableEntity, nil } templateMap["Status"] = "OK" - templateMap["Message"] = l10n.T.GetPath(lang, "UserProfile", "VerificationSuccess").(string) + templateMap["Message"] = supplements.Localization[lang].UserProfile.VerificationSuccess 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 12dc5cf..32fba7e 100644 --- a/internal/router/handlers/api-v1-subs-put.go +++ b/internal/router/handlers/api-v1-subs-put.go @@ -3,7 +3,6 @@ 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" ) @@ -53,18 +52,18 @@ func (r *PutSubsHandler) Render(c *fiber.Ctx, supplements *router.Supplements, l subscriptionTypeEnum = mailer.Specific default: templateMap["Status"] = "Failed" - templateMap["Message"] = l10n.T.GetPath(lang, "UserProfile", "SubscribeInvalidType").(string) + templateMap["Message"] = supplements.Localization[lang].UserProfile.SubscribeInvalidType 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"] = l10n.T.GetPath(lang, "UserProfile", "FailedToSubscribe").(string) + templateMap["Message"] = supplements.Localization[lang].UserProfile.FailedToSubscribe return fiber.StatusUnprocessableEntity, nil } templateMap["Status"] = "OK" - templateMap["Message"] = l10n.T.GetPath(lang, "UserProfile", "SubscribedSuccessfully").(string) + templateMap["Message"] = supplements.Localization[lang].UserProfile.SubscribedSuccessfully return fiber.StatusOK, nil } diff --git a/internal/router/handlers/lang-blog.go b/internal/router/handlers/lang-blog.go index c31c2eb..9f7947b 100644 --- a/internal/router/handlers/lang-blog.go +++ b/internal/router/handlers/lang-blog.go @@ -11,7 +11,6 @@ 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" ) @@ -58,8 +57,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: l10n.T.GetPath(lang, "BlogSearch", "Header").(string)}, - {Property: "og:description", Content: l10n.T.GetPath(lang, "BlogSearch", "Description").(string)}, + {Property: "og:title", Content: supplements.Localization[lang].BlogSearch.Header}, + {Property: "og:description", Content: supplements.Localization[lang].BlogSearch.Description}, {Property: "og:url", Content: fmt.Sprintf("%s/%s/blog", templateMap["CanonicalEndpoint"], lang)}, {Property: "og:type", Content: "website"}, }, nil @@ -86,14 +85,14 @@ func (r *CatalogueHandler) RenderBody(c *fiber.Ctx, supplements *router.Suppleme templateMap["Tags"] = tagsArray templateMap["QuerySort"] = querySort templateMap["QueryTags"] = strings.Join(queryTags, ",") - templateMap["Title"] = l10n.T.GetPath(lang, "BlogSearch", "Header").(string) + templateMap["Title"] = supplements.Localization[lang].BlogSearch.Header 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"] = l10n.T.GetPath(lang, "BlogSearch", "Header").(string) + templateMap["Title"] = supplements.Localization[lang].BlogSearch.Header return fiber.StatusOK, nil } diff --git a/internal/router/handlers/lang-user-unsubscribe.go b/internal/router/handlers/lang-user-unsubscribe.go index e22d854..4fbd244 100644 --- a/internal/router/handlers/lang-user-unsubscribe.go +++ b/internal/router/handlers/lang-user-unsubscribe.go @@ -4,7 +4,6 @@ import ( "log/slog" "github.com/SayaAndy/saya-today-web/internal/router" - "github.com/SayaAndy/saya-today-web/l10n" "github.com/gofiber/fiber/v2" ) @@ -40,24 +39,24 @@ func (r *UnsubscribeHandler) Render(c *fiber.Ctx, supplements *router.Supplement if unsubscribeCode == "" { statusColor = "0, 0, 255" statusEmoji = "(╭ರ_•́)" - statusText = l10n.T.GetPath(lang, "UnsubscribePage", "UnsetCode").(string) + statusText = supplements.Localization[lang].UnsubscribePage.UnsetCode 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 = l10n.T.GetPath(lang, "UnsubscribePage", "InvalidCode").(string) + statusText = supplements.Localization[lang].UnsubscribePage.InvalidCode 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 = l10n.T.GetPath(lang, "UnsubscribePage", "OnServerError").(string) + statusText = supplements.Localization[lang].UnsubscribePage.OnServerError status = fiber.ErrInternalServerError.Code } else { statusColor = "0, 255, 0" statusEmoji = "♡⸜(˶˃ ᵕ ˂˶)⸝♡" - statusText = l10n.T.GetPath(lang, "UnsubscribePage", "Success").(string) + statusText = supplements.Localization[lang].UnsubscribePage.Success status = fiber.StatusOK } diff --git a/internal/router/handlers/lang-user.go b/internal/router/handlers/lang-user.go index 085a9aa..0dda529 100644 --- a/internal/router/handlers/lang-user.go +++ b/internal/router/handlers/lang-user.go @@ -6,7 +6,6 @@ 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" ) @@ -41,15 +40,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: l10n.T.GetPath(lang, "UserProfile", "Header").(string)}, - {Property: "og:description", Content: l10n.T.GetPath(lang, "UserProfile", "Description").(string)}, + {Property: "og:title", Content: supplements.Localization[lang].UserProfile.Header}, + {Property: "og:description", Content: supplements.Localization[lang].UserProfile.Description}, {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"] = l10n.T.GetPath(lang, "UserProfile", "Header").(string) + templateMap["Title"] = supplements.Localization[lang].UserProfile.Header email, _, err := supplements.Mailer.GetInfo(supplements.Mailer.GetHash(c.IP())) if err != nil { @@ -84,6 +83,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"] = l10n.T.GetPath(lang, "UserProfile", "Header").(string) + templateMap["Title"] = supplements.Localization[lang].UserProfile.Header return fiber.StatusOK, nil } diff --git a/internal/router/handlers/lang.go b/internal/router/handlers/lang.go index cc0b33b..25b5036 100644 --- a/internal/router/handlers/lang.go +++ b/internal/router/handlers/lang.go @@ -6,7 +6,6 @@ import ( "time" "github.com/SayaAndy/saya-today-web/internal/router" - "github.com/SayaAndy/saya-today-web/l10n" "github.com/gofiber/fiber/v2" ) @@ -52,8 +51,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: l10n.T.GetPath(lang, "HomePage", "Header").(string)}, - {Property: "og:description", Content: l10n.T.GetPath(lang, "HomePage", "HomePageDescription").(string)}, + {Property: "og:title", Content: supplements.Localization[lang].HomePage.Header}, + {Property: "og:description", Content: supplements.Localization[lang].HomePage.HomePageDescription}, {Property: "og:image", Content: fmt.Sprintf( supplements.PhotoStorage.HomePageGifs.BaseUrl, supplements.PhotoStorage.HomePageGifs.Indexes[rand.Int()%len(supplements.PhotoStorage.HomePageGifs.Indexes)], @@ -64,7 +63,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"] = l10n.T.GetPath(lang, "HomePage", "Header").(string) + templateMap["Title"] = supplements.Localization[lang].HomePage.Header templateMap["FilledHeartCount"] = uint(40) templateMap["OutlineHeartCount"] = uint(40) templateMap["GifUrl"] = fmt.Sprintf( @@ -76,6 +75,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"] = l10n.T.GetPath(lang, "HomePage", "Header").(string) + templateMap["Title"] = supplements.Localization[lang].HomePage.Header return fiber.StatusOK, nil } diff --git a/internal/router/router.go b/internal/router/router.go index 43d6138..a1208e0 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -23,6 +23,7 @@ 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" @@ -94,6 +95,7 @@ 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] @@ -147,7 +149,16 @@ 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 blog client: type %s: %w", cfg.BlogPages.Storage.Type, err) + 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 } supplements.MarkdownRenderer = goldmark.New( @@ -189,7 +200,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)) + cfg.Mail.PublicName, cfg.Mail.MailAddress, cfg.Mail.Username, cfg.Mail.Password, []byte(cfg.Mail.Salt), supplements.Localization) if err != nil { return nil, fmt.Errorf("fail to initialize mailer: %w", err) } @@ -303,6 +314,7 @@ func (r *Router) InitRoutes() (err error) { } defaultMap := fiber.Map{ + "L": r.supplements.Localization[lang], "Lang": lang, "Path": trimmedPath, "QueryString": queryString, @@ -455,6 +467,7 @@ 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, @@ -580,6 +593,7 @@ 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, diff --git a/internal/templatemanager/templatemanager.go b/internal/templatemanager/templatemanager.go index 5c84418..9d14e15 100644 --- a/internal/templatemanager/templatemanager.go +++ b/internal/templatemanager/templatemanager.go @@ -8,8 +8,6 @@ import ( "path/filepath" "strings" "time" - - "github.com/SayaAndy/saya-today-web/l10n" ) type TemplateManager struct { @@ -40,9 +38,6 @@ var templateFuncMap = template.FuncMap{ "fdiv": func(a, b int) float64 { return float64(a) / float64(b) }, - "l": func(path ...any) any { - return l10n.T.GetPath(path...) - }, } func NewTemplateManager(templates ...TemplateManagerTemplates) (*TemplateManager, error) { |