summaryrefslogtreecommitdiffci
path: root/l10n
diff refs
from: back
to: back
| flip
diff options
context:
space:
mode:
Diffstat (limited to 'l10n')
-rw-r--r--l10n/en.yaml79
-rw-r--r--l10n/ru.yaml79
-rw-r--r--l10n/translator-hook.go39
-rw-r--r--l10n/translator.go167
4 files changed, 0 insertions, 364 deletions
diff --git a/l10n/en.yaml b/l10n/en.yaml
deleted file mode 100644
index 9571aca..0000000
--- a/l10n/en.yaml
+++ /dev/null
@@ -1,79 +0,0 @@
-TagsLabel: "Tags:"
-BlogSearch:
- Header: "Blog Search"
- Description: "The Saya Blog posts' list"
- TagsHeader: "Tags"
- OrderByHeader: "Order by..."
- TitleOrdered: "Title"
- ActionDateOrdered: "Action Date"
- PublicationDateOrdered: "Publication Date"
- ChooseAllTags: "Choose All"
-GlobalMap:
- Header: "Global Map"
- Description: "Global map with all the tags of places I've been to"
-HomePage:
- Header: "Home Page"
- Contacts: "Contacts"
- DidYouKnowThat: "Did you know, that..."
- SidebarDescription: "Describing the Sidebar"
- BackDescription: "This button will lead back to higher page (like Home => Language Pick, Blog Search => Home)"
- HomePageDescription: "Home Page -- where we are right now!"
- BlogSearchDescription: "Blog Search. You can find my travel notes there and, maybe, something else!"
- MarkerMapDescription: "Map with markers of my travel notes -- a convinient way to find an interesting region and find related posts!"
- ThemeSwitchDescription: "Theme Palette lets you change the theme of the site -- there are 2 dark and 3 bright themes currently!"
- AccountDescription: "This is where you can subscribe to any blog update via E-mail!"
- Hymn1: "We welcome you to Sayasite!"
- Hymn2: "We've been expecting you!"
- Hymn3: "You bring such joy in Sayasite!"
- Hymn4: "No matter where you roam, know our love is true!~"
-UnsubscribePage:
- Header: "Cancelling the Subscription"
- UnsetCode: "Your cancel code is not set. You just having a walk around the site?"
- InvalidCode: "Your cancel code could not be verified. Maybe, the code expired after a day. Or maybe, you've already unsubscribed."
- OnServerError: "We couldn't unsubscribe you, the problem is on our side! We will solve this problem as soon as possible."
- Success: "Cancelled your subscription successfully! We do hope we will engage you again someday."
-Metadata:
- Published: "Published"
- Action: "Took place on"
-Mail:
- UnsubscribeFooter: "If this letter got you in a bad mood, you can unsubscribe from my blog by {}this link{/}."
- VerifyEmail:
- Subject: "Verification Link for SAYA.UZ is waiting for you!"
- Welcome: "Greetings!"
- Intro: "There are 2 ways for us to validate your profile:"
- GotoLink: "Go by this link:"
- InputCode: "Or input this code on the personal page:"
- IfRandom: "If you are unsure what this letter this, you can ignore it, and also, if you are interested, you may visit my site :)"
- NewPost:
- Subject: "A new post arrived at SAYA.UZ!"
- Intro: "A new post came!"
- CapturedOn: "Captured on"
-UserProfile:
- Header: "Personal Settings"
- Description: "Set and verify your e-mail here, as well as subscribe to favorite blog tags"
- EmailHeader: "E-Mail"
- VerificationCodeHeader: "Verification Code"
- TypeEmail: "Please type your email"
- SendCodeButton: "Send Code"
- VerifyButton: "Verify"
- VerificationCodeSent: "Verification code sent! Please check your e-mail. Your next verification attempt will be possible on {}."
- DelayTilVerification: "You have already requested the verification before! Please wait until {} for a new verification request."
- FailedEmailRender: "Failed to render the email status message, please ask administrator for a more detailed cause."
- VerificationCodeSendingError: "Failed to send a verification code, please ask administrator for a more detailed cause."
- EmailAlreadyValidated: "You already have this E-Mail validated."
- EmailTaken: "This E-Mail is already taken."
- EmailEmpty: "E-Mail is unset or empty."
- VerificationSuccess: "Success! You are now able to subscribe with your new e-mail."
- VerificationFailed: "Verification code is invalid, please ask administrator for a more detailed cause."
- VerificationEmpty: "Verification code is unset or empty."
- SubscriptionHeader: "Subscribe to..."
- TagsNone: "None"
- TagsAll: "All"
- TagsSpecific: "Specific"
- TagDoesNotExist: 'The tag "{}" does not exist on the site.'
- TagAlreadyAdded: 'The tag "{}" is already in your subscribed list.'
- SaveButton: "Save"
- SubscribeInvalidType: "Invalid subscription type."
- FailedToSubscribe: "Failed to subscribe by new settings, please ask administrator for a more detailed cause."
- SubscribedSuccessfully: "Successfully subscribed you by new settings!"
- RefreshPage: "Please refresh the profile page on the device, where you requested the code."
diff --git a/l10n/ru.yaml b/l10n/ru.yaml
deleted file mode 100644
index 1818998..0000000
--- a/l10n/ru.yaml
+++ /dev/null
@@ -1,79 +0,0 @@
-TagsLabel: "Тэги:"
-BlogSearch:
- Header: "Поиск по блогу"
- Description: "Каталог записей Saya Blog"
- TagsHeader: "Тэги"
- OrderByHeader: "Упорядочить по..."
- TitleOrdered: "названию"
- ActionDateOrdered: "дате действия"
- PublicationDateOrdered: "времени публикации"
- ChooseAllTags: "Выбрать все"
-GlobalMap:
- Header: "Глобальная карта"
- Description: "Глобальная карта с метками мест, где я побывал"
-HomePage:
- Header: "Домашняя страница"
- Contacts: "Контакты"
- DidYouKnowThat: "А вы знали, что..."
- SidebarDescription: "Поясняем за сайдбар"
- BackDescription: "Эта кнопка позволяет идти на страницу вверх (т.е. Домашняя страница => Выбор языка, Поиск по блогу => Домашняя страница)"
- HomePageDescription: "Домашняя страница -- где мы сейчас и находимся!"
- BlogSearchDescription: "Поиск по блогу. Там размещены мои путевые заметки и, может, что-то ещё!"
- MarkerMapDescription: "Карта с маркерами моих путевых заметок, -- удобный способ найти интересный регион и перейти на заинтересовавшие посты!"
- ThemeSwitchDescription: "Позволяет поменять тему сайта -- есть 3 светлые и 2 тёмные темы!"
- AccountDescription: "Здесь можно подписаться на обновления в блоге, используя электронную почту!"
- Hymn1: "Приветствуем Вас на Саясайте!"
- Hymn2: "Мы Вас столько ждали!"
- Hymn3: "Столько радости от Вас на Саясайте!"
- Hymn4: "Где бы Вы не были, знайте, -- наша любовь крепка!"
-UnsubscribePage:
- Header: "Отписка"
- UnsetCode: "Код для отписки не проставлен. Вы случайно не заблудились?"
- InvalidCode: "Код для отписки не подтверждён. Может, истекло время в сутки для кода. А может, вы уже успели отписаться."
- OnServerError: "Мы не смогли вас отписать, проблема на нашей стороне! В скором времени займёмся проблемой."
- Success: "Вы отписались от рассылки! Надеюсь, мы ещё сможем вас заинтересовать."
-Metadata:
- Published: "Опубликовано"
- Action: "Время действия"
-Mail:
- UnsubscribeFooter: "Если данное письмо пришло вам случайно, либо вы хотите отписаться, можете перейти по {}этой ссылке{/}."
- VerifyEmail:
- Subject: "Ссылка для верификации для подтверждения вашей почты SAYA.UZ"
- Welcome: "Приветствую!"
- Intro: "Есть 2 способа, чтобы подтвердить свою электронную почту:"
- GotoLink: "Перейти по этой ссылке:"
- InputCode: "Либо ввести этот код на странице подписок:"
- IfRandom: "Если ты не понимаешь, что это за спам, можешь проигнорировать это письмо, а ещё, если интересно, можешь посетить мой сайт :)"
- NewPost:
- Subject: "Новый пост на SAYA.UZ!"
- Intro: "Вышел новый пост!"
- CapturedOn: "Снималось"
-UserProfile:
- Header: "Личные настройки"
- Description: "Здесь можно настроить и верифицировать свою электронную почту, а также подписаться на избранные темы блога"
- EmailHeader: "E-Mail"
- VerificationCodeHeader: "Код верификации"
- TypeEmail: "Пожалуйста, введите свою почту"
- SendCodeButton: "Отправить код"
- VerifyButton: "Верифицировать"
- VerificationCodeSent: "Выслали вам код верификации! Проверьте свою почту. Следующая попытка верификации будет возможна {}."
- DelayTilVerification: "Вы уже запрашивали недавно верификацию! Дождитесь {} для новой попытки."
- FailedEmailRender: "Неудачная попытка создать электронное письмо, более подробно спрашивайте у администратора."
- VerificationCodeSendingError: "Неудачная попытка прислать код для верификации, более подробно спрашивайте у администратора."
- EmailAlreadyValidated: "Эту почту вы уже подтверждали."
- EmailTaken: "Эта почта уже занята."
- EmailEmpty: "Почта не введена."
- VerificationSuccess: "Поздравляем! Теперь по этой почте можно подписаться на блог."
- VerificationFailed: "Код для верификации невалиден, при вопросах, пожалуйста, обращайтесь к администратору."
- VerificationEmpty: "Код для верификации не введён."
- SubscriptionHeader: "Подписаться на..."
- TagsNone: "Ничего"
- TagsAll: "Всё"
- TagsSpecific: "Определённое"
- TagDoesNotExist: 'Тэга "{}" нет на сайте.'
- TagAlreadyAdded: 'Тэг "{}" уже у вас добавлен.'
- SaveButton: "Сохранить"
- SubscribeInvalidType: "Неизвестный тип подписки."
- FailedToSubscribe: "Неудачная попытка записать новую подписку, более подробно спрашивайте у администратора."
- SubscribedSuccessfully: "Вы успешно подписались по новым настройкам!"
- RefreshPage: "Пожалуйста, обновите страницу с профилем на устройстве, откуда запрашивали код."
diff --git a/l10n/translator-hook.go b/l10n/translator-hook.go
deleted file mode 100644
index ff5837c..0000000
--- a/l10n/translator-hook.go
+++ /dev/null
@@ -1,39 +0,0 @@
-package l10n
-
-var hooks map[string]*TranslatorHook
-
-type TranslatorHook struct {
- t *Translator
- prefix string
-}
-
-func NewTranslatorHook(prefix string) *TranslatorHook {
- if _, ok := hooks[prefix]; !ok {
- hooks[prefix] = &TranslatorHook{T, prefix}
- }
- return hooks[prefix]
-}
-
-func (h *TranslatorHook) Set(key string, val any, toOverwrite bool) (alreadySet bool, err error) {
- return h.t.Set(h.prefix+key, val, toOverwrite)
-}
-
-func (h *TranslatorHook) SetPath(val any, toOverwrite bool, path ...any) (alreadySet bool, err error) {
- return h.t.SetPath(val, toOverwrite, append([]any{h.prefix}, path...)...)
-}
-
-func (h *TranslatorHook) Get(key string) any {
- return h.t.Get(h.prefix + "." + key)
-}
-
-func (h *TranslatorHook) GetPath(path ...any) any {
- return h.t.GetPath(append([]any{h.prefix}, path...)...)
-}
-
-func (h *TranslatorHook) GetDefault(key string, def any) any {
- return h.t.GetDefault(h.prefix+"."+key, def)
-}
-
-func (h *TranslatorHook) GetDefaultPath(def any, path ...any) any {
- return h.t.GetDefaultPath(def, append([]any{h.prefix}, path...)...)
-}
diff --git a/l10n/translator.go b/l10n/translator.go
deleted file mode 100644
index 4d4b4eb..0000000
--- a/l10n/translator.go
+++ /dev/null
@@ -1,167 +0,0 @@
-package l10n
-
-import (
- "errors"
- "fmt"
- "log/slog"
- "os"
- "strings"
- "sync"
-
- "gopkg.in/yaml.v3"
-)
-
-var T *Translator
-
-func init() {
- var err error
- if T, err = NewTranslator("ru", "en"); err != nil {
- slog.Error("fail to load localization", slog.String("error", err.Error()))
- os.Exit(1)
- }
-}
-
-type Translator struct {
- l map[string]any
- mu sync.RWMutex
-}
-
-func NewTranslator(locales ...string) (*Translator, error) {
- t := &Translator{l: make(map[string]any)}
- errs := make([]error, 0)
-
- for _, locale := range locales {
- contentBytes, err := os.ReadFile(fmt.Sprintf("l10n/%s.yaml", locale))
- if err != nil {
- errs = append(errs, fmt.Errorf("opening one of files: l10n/%s.yaml: %w", locale, err))
- continue
- }
-
- var content map[string]any
- if err := yaml.Unmarshal(contentBytes, &content); err != nil {
- errs = append(errs, fmt.Errorf("parsing one of files: l10n/%s.yaml: %w", locale, err))
- continue
- }
-
- errs = append(errs, t.initMap("."+locale, content)...)
- }
-
- return t, errors.Join(errs...)
-}
-
-func (t *Translator) Set(key string, val any, toOverwrite bool) (alreadySet bool, err error) {
- t.mu.RLock()
- if _, alreadySet = t.l[key]; !alreadySet || (alreadySet && toOverwrite) {
- t.mu.RUnlock()
- return alreadySet, errors.Join(t.setSafe(key, val)...)
- }
- t.mu.RUnlock()
- return alreadySet, nil
-}
-
-func (t *Translator) SetPath(val any, toOverwrite bool, path ...any) (alreadySet bool, err error) {
- key, err := formatPath(path...)
- if err != nil {
- return false, err
- }
- return t.Set(key, val, toOverwrite)
-}
-
-func (t *Translator) Get(key string) any {
- return t.GetDefault(key, key[strings.LastIndex(key, ".")+1:])
-}
-
-func (t *Translator) GetPath(path ...any) any {
- return t.GetDefaultPath(path[len(path)-1], path...)
-}
-
-func (t *Translator) GetDefault(key string, def any) any {
- t.mu.RLock()
- defer t.mu.RUnlock()
- if v, ok := t.l[key]; ok {
- return v
- }
- slog.Warn("failed to find localization for a key", slog.String("key", key))
- return def
-}
-
-func (t *Translator) GetDefaultPath(def any, path ...any) any {
- t.mu.RLock()
- defer t.mu.RUnlock()
- key, err := formatPath(path...)
- if err != nil {
- slog.Error("get localized value by path: path is invalid", slog.String("error", err.Error()))
- return def
- }
- return t.GetDefault(key, def)
-}
-
-func (t *Translator) initSlice(parent string, level []any) []error {
- errs := make([]error, 0)
- for i, v := range level {
- newParent := parent + fmt.Sprintf("[%d]", i)
- t.setSafe(newParent, v)
- }
- return errs
-}
-
-func (t *Translator) initMap(parent string, level map[string]any) []error {
- errs := make([]error, 0)
- for k, v := range level {
- key, err := formatPath(k)
- if err != nil {
- errs = append(errs, err)
- continue
- }
-
- errs = append(errs, t.setSafe(parent+key, v)...)
- }
- return errs
-}
-
-func (t *Translator) setSafe(k string, v any) []error {
- errs := make([]error, 0)
- t.mu.Lock()
- switch vv := v.(type) {
- case int:
- t.l[k] = vv
- t.mu.Unlock()
- case float64:
- t.l[k] = vv
- t.mu.Unlock()
- case string:
- t.l[k] = vv
- t.mu.Unlock()
- case []any:
- t.mu.Unlock()
- errs = append(errs, t.initSlice(k, vv)...)
- case map[string]any:
- t.mu.Unlock()
- errs = append(errs, t.initMap(k, vv)...)
- default:
- t.mu.Unlock()
- errs = append(errs, fmt.Errorf("invalid value type: %s, %v", k, vv))
- }
- return errs
-}
-
-func formatPath(path ...any) (string, error) {
- var key string
- for _, part := range path {
- switch k := part.(type) {
- case int:
- key += fmt.Sprintf("[%d]", k)
- case string:
- key += "." + strings.ReplaceAll(k, ".", "\\.")
- case []any:
- add, err := formatPath(k...)
- if err != nil {
- return "", fmt.Errorf("while formatting nested slice: %w", err)
- }
- key += add
- default:
- return "", fmt.Errorf("invalid key part: after %s follows %v", key, k)
- }
- }
- return key, nil
-}