Make better use of i18n (#20096)

* Prototyping

* Start work on creating offsets

* Modify tests

* Start prototyping with actual MPH

* Twiddle around

* Twiddle around comments

* Convert templates

* Fix external languages

* Fix latest translation

* Fix some test

* Tidy up code

* Use simple map

* go mod tidy

* Move back to data structure

- Uses less memory by creating for each language a map.

* Apply suggestions from code review

Co-authored-by: delvh <dev.lh@web.de>

* Add some comments

* Fix tests

* Try to fix tests

* Use en-US as defacto fallback

* Use correct slices

* refactor (#4)

* Remove TryTr, add log for missing translation key

* Refactor i18n

- Separate dev and production locale stores.
- Allow for live-reloading in dev mode.

Co-authored-by: zeripath <art27@cantab.net>

* Fix live-reloading & check for errors

* Make linter happy

* live-reload with periodic check (#5)

* Fix tests

Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: zeripath <art27@cantab.net>
This commit is contained in:
Gusted 2022-06-26 16:19:22 +02:00 committed by GitHub
parent 711cbcce8d
commit 5d3f99c7c6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
60 changed files with 340 additions and 282 deletions

View file

@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/sync"
"code.gitea.io/gitea/modules/translation"
"github.com/gogs/cron"
)
@ -63,7 +64,7 @@ type TaskTableRow struct {
task *Task
}
func (t *TaskTableRow) FormatLastMessage(locale string) string {
func (t *TaskTableRow) FormatLastMessage(locale translation.Locale) string {
if t.Status == "finished" {
return t.task.GetConfig().FormatMessage(locale, t.Name, t.Status, t.LastDoer)
}

View file

@ -7,7 +7,7 @@ package cron
import (
"time"
"code.gitea.io/gitea/modules/translation/i18n"
"code.gitea.io/gitea/modules/translation"
)
// Config represents a basic configuration interface that cron task
@ -15,7 +15,7 @@ type Config interface {
IsEnabled() bool
DoRunAtStart() bool
GetSchedule() string
FormatMessage(locale, name, status, doer string, args ...interface{}) string
FormatMessage(locale translation.Locale, name, status, doer string, args ...interface{}) string
DoNoticeOnSuccess() bool
}
@ -69,9 +69,9 @@ func (b *BaseConfig) DoNoticeOnSuccess() bool {
// FormatMessage returns a message for the task
// Please note the `status` string will be concatenated with `admin.dashboard.cron.` and `admin.dashboard.task.` to provide locale messages. Similarly `name` will be composed with `admin.dashboard.` to provide the locale name for the task.
func (b *BaseConfig) FormatMessage(locale, name, status, doer string, args ...interface{}) string {
func (b *BaseConfig) FormatMessage(locale translation.Locale, name, status, doer string, args ...interface{}) string {
realArgs := make([]interface{}, 0, len(args)+2)
realArgs = append(realArgs, i18n.Tr(locale, "admin.dashboard."+name))
realArgs = append(realArgs, locale.Tr("admin.dashboard."+name))
if doer == "" {
realArgs = append(realArgs, "(Cron)")
} else {
@ -81,7 +81,7 @@ func (b *BaseConfig) FormatMessage(locale, name, status, doer string, args ...in
realArgs = append(realArgs, args...)
}
if doer == "" {
return i18n.Tr(locale, "admin.dashboard.cron."+status, realArgs...)
return locale.Tr("admin.dashboard.cron."+status, realArgs...)
}
return i18n.Tr(locale, "admin.dashboard.task."+status, realArgs...)
return locale.Tr("admin.dashboard.task."+status, realArgs...)
}

View file

@ -94,7 +94,7 @@ func (t *Task) RunWithUser(doer *user_model.User, config Config) {
doerName = doer.Name
}
ctx, _, finished := pm.AddContext(baseCtx, config.FormatMessage("en-US", t.Name, "process", doerName))
ctx, _, finished := pm.AddContext(baseCtx, config.FormatMessage(translation.NewLocale("en-US"), t.Name, "process", doerName))
defer finished()
if err := t.fun(ctx, doer, config); err != nil {
@ -114,7 +114,7 @@ func (t *Task) RunWithUser(doer *user_model.User, config Config) {
t.LastDoer = doerName
t.lock.Unlock()
if err := admin_model.CreateNotice(ctx, admin_model.NoticeTask, config.FormatMessage("en-US", t.Name, "cancelled", doerName, message)); err != nil {
if err := admin_model.CreateNotice(ctx, admin_model.NoticeTask, config.FormatMessage(translation.NewLocale("en-US"), t.Name, "cancelled", doerName, message)); err != nil {
log.Error("CreateNotice: %v", err)
}
return
@ -127,7 +127,7 @@ func (t *Task) RunWithUser(doer *user_model.User, config Config) {
t.lock.Unlock()
if config.DoNoticeOnSuccess() {
if err := admin_model.CreateNotice(ctx, admin_model.NoticeTask, config.FormatMessage("en-US", t.Name, "finished", doerName)); err != nil {
if err := admin_model.CreateNotice(ctx, admin_model.NoticeTask, config.FormatMessage(translation.NewLocale("en-US"), t.Name, "finished", doerName)); err != nil {
log.Error("CreateNotice: %v", err)
}
}
@ -148,7 +148,7 @@ func RegisterTask(name string, config Config, fun func(context.Context, *user_mo
log.Debug("Registering task: %s", name)
i18nKey := "admin.dashboard." + name
if _, ok := translation.TryTr("en-US", i18nKey); !ok {
if value := translation.NewLocale("en-US").Tr(i18nKey); value == i18nKey {
return fmt.Errorf("translation is missing for task %q, please add translation for %q", name, i18nKey)
}

View file

@ -75,8 +75,8 @@ func sendUserMail(language string, u *user_model.User, tpl base.TplName, code, s
locale := translation.NewLocale(language)
data := map[string]interface{}{
"DisplayName": u.DisplayName(),
"ActiveCodeLives": timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, language),
"ResetPwdCodeLives": timeutil.MinutesToFriendly(setting.Service.ResetPwdCodeLives, language),
"ActiveCodeLives": timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, locale),
"ResetPwdCodeLives": timeutil.MinutesToFriendly(setting.Service.ResetPwdCodeLives, locale),
"Code": code,
"Language": locale.Language(),
// helper
@ -126,7 +126,7 @@ func SendActivateEmailMail(u *user_model.User, email *user_model.EmailAddress) {
locale := translation.NewLocale(u.Language)
data := map[string]interface{}{
"DisplayName": u.DisplayName(),
"ActiveCodeLives": timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, locale.Language()),
"ActiveCodeLives": timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, locale),
"Code": u.GenerateEmailActivateCode(email.Email),
"Email": email.Email,
"Language": locale.Language(),