From 99d4a266b9aac13f20244b9fe0fce998d2c34b30 Mon Sep 17 00:00:00 2001
From: wxiaoguang
Date: Fri, 31 Dec 2021 20:02:49 +0800
Subject: [PATCH 1/7] Unify and simplify TrN for i18n
---
modules/csv/csv_test.go | 14 ++--
modules/templates/helper.go | 64 -------------------
modules/test/context_tests.go | 4 ++
modules/translation/translation.go | 64 +++++++++++++++++++
routers/web/repo/migrate.go | 7 +-
routers/web/repo/repo.go | 7 +-
routers/web/repo/setting.go | 7 +-
services/mailer/mail.go | 5 --
services/mailer/mail_release.go | 1 -
services/mailer/mail_repo.go | 1 -
templates/mail/issue/default.tmpl | 2 +-
templates/repo/activity.tmpl | 55 ++++++++++------
templates/repo/blame.tmpl | 2 +-
templates/repo/create.tmpl | 2 +-
.../repo/issue/view_content/comments.tmpl | 6 +-
templates/repo/issue/view_content/pull.tmpl | 4 +-
templates/repo/sub_menu.tmpl | 6 +-
templates/repo/view_file.tmpl | 2 +-
templates/shared/issuelist.tmpl | 8 +--
19 files changed, 132 insertions(+), 129 deletions(-)
diff --git a/modules/csv/csv_test.go b/modules/csv/csv_test.go
index d72c3e3a7329c..09b718bae8f63 100644
--- a/modules/csv/csv_test.go
+++ b/modules/csv/csv_test.go
@@ -47,11 +47,11 @@ a, b c
e f
g h i
j l
-m n,
+m n,
p q r
u
v w x
-y
+y
`,
expectedRows: [][]string{
{"col1", "col2", "col3"},
@@ -74,7 +74,7 @@ y
a, b, c
d,e,f
,h, i
-j, ,
+j, ,
, , `,
expectedRows: [][]string{
{"col1", "col2", "col3"},
@@ -353,7 +353,7 @@ John Doe john@doe.com This,note,had,a,lot,of,commas,to,test,delimters`,
quoted,
text," a
2 "some,
-quoted,
+quoted,
text," b
3 "some,
quoted,
@@ -459,7 +459,7 @@ func TestGuessFromBeforeAfterQuotes(t *testing.T) {
quoted,
text," a
2 "some,
-quoted,
+quoted,
text," b
3 "some,
quoted,
@@ -549,6 +549,10 @@ func (l mockLocale) Tr(s string, _ ...interface{}) string {
return s
}
+func (l mockLocale) TrN(_cnt interface{}, key1, _keyN string, _args ...interface{}) string {
+ return key1
+}
+
func TestFormatError(t *testing.T) {
var cases = []struct {
err error
diff --git a/modules/templates/helper.go b/modules/templates/helper.go
index a05c0c1a95ff1..fc07b49c71925 100644
--- a/modules/templates/helper.go
+++ b/modules/templates/helper.go
@@ -239,7 +239,6 @@ func NewFuncMap() []template.FuncMap {
"DisableImportLocal": func() bool {
return !setting.ImportLocalPaths
},
- "TrN": TrN,
"Dict": func(values ...interface{}) (map[string]interface{}, error) {
if len(values)%2 != 0 {
return nil, errors.New("invalid dict call")
@@ -857,69 +856,6 @@ func DiffLineTypeToStr(diffType int) string {
return "same"
}
-// Language specific rules for translating plural texts
-var trNLangRules = map[string]func(int64) int{
- "en-US": func(cnt int64) int {
- if cnt == 1 {
- return 0
- }
- return 1
- },
- "lv-LV": func(cnt int64) int {
- if cnt%10 == 1 && cnt%100 != 11 {
- return 0
- }
- return 1
- },
- "ru-RU": func(cnt int64) int {
- if cnt%10 == 1 && cnt%100 != 11 {
- return 0
- }
- return 1
- },
- "zh-CN": func(cnt int64) int {
- return 0
- },
- "zh-HK": func(cnt int64) int {
- return 0
- },
- "zh-TW": func(cnt int64) int {
- return 0
- },
- "fr-FR": func(cnt int64) int {
- if cnt > -2 && cnt < 2 {
- return 0
- }
- return 1
- },
-}
-
-// TrN returns key to be used for plural text translation
-func TrN(lang string, cnt interface{}, key1, keyN string) string {
- var c int64
- if t, ok := cnt.(int); ok {
- c = int64(t)
- } else if t, ok := cnt.(int16); ok {
- c = int64(t)
- } else if t, ok := cnt.(int32); ok {
- c = int64(t)
- } else if t, ok := cnt.(int64); ok {
- c = t
- } else {
- return keyN
- }
-
- ruleFunc, ok := trNLangRules[lang]
- if !ok {
- ruleFunc = trNLangRules["en-US"]
- }
-
- if ruleFunc(c) == 0 {
- return key1
- }
- return keyN
-}
-
// MigrationIcon returns a SVG name matching the service an issue/comment was migrated from
func MigrationIcon(hostname string) string {
switch hostname {
diff --git a/modules/test/context_tests.go b/modules/test/context_tests.go
index 1f893122f3f73..62ec21f6fe176 100644
--- a/modules/test/context_tests.go
+++ b/modules/test/context_tests.go
@@ -103,6 +103,10 @@ func (l mockLocale) Tr(s string, _ ...interface{}) string {
return s
}
+func (l mockLocale) TrN(_cnt interface{}, key1, _keyN string, _args ...interface{}) string {
+ return key1
+}
+
type mockResponseWriter struct {
httptest.ResponseRecorder
size int
diff --git a/modules/translation/translation.go b/modules/translation/translation.go
index 77cc9ac7f5847..aa5bd928d0f99 100644
--- a/modules/translation/translation.go
+++ b/modules/translation/translation.go
@@ -17,6 +17,7 @@ import (
type Locale interface {
Language() string
Tr(string, ...interface{}) string
+ TrN(cnt interface{}, key1, keyN string, args ...interface{}) string
}
// LangType represents a lang type
@@ -99,3 +100,66 @@ func (l *locale) Language() string {
func (l *locale) Tr(format string, args ...interface{}) string {
return i18n.Tr(l.Lang, format, args...)
}
+
+// Language specific rules for translating plural texts
+var trNLangRules = map[string]func(int64) int{
+ "en-US": func(cnt int64) int {
+ if cnt == 1 {
+ return 0
+ }
+ return 1
+ },
+ "lv-LV": func(cnt int64) int {
+ if cnt%10 == 1 && cnt%100 != 11 {
+ return 0
+ }
+ return 1
+ },
+ "ru-RU": func(cnt int64) int {
+ if cnt%10 == 1 && cnt%100 != 11 {
+ return 0
+ }
+ return 1
+ },
+ "zh-CN": func(cnt int64) int {
+ return 0
+ },
+ "zh-HK": func(cnt int64) int {
+ return 0
+ },
+ "zh-TW": func(cnt int64) int {
+ return 0
+ },
+ "fr-FR": func(cnt int64) int {
+ if cnt > -2 && cnt < 2 {
+ return 0
+ }
+ return 1
+ },
+}
+
+// TrN returns translated message for plural text translation
+func (l *locale) TrN(cnt interface{}, key1, keyN string, args ...interface{}) string {
+ var c int64
+ if t, ok := cnt.(int); ok {
+ c = int64(t)
+ } else if t, ok := cnt.(int16); ok {
+ c = int64(t)
+ } else if t, ok := cnt.(int32); ok {
+ c = int64(t)
+ } else if t, ok := cnt.(int64); ok {
+ c = t
+ } else {
+ return l.Tr(keyN, args...)
+ }
+
+ ruleFunc, ok := trNLangRules[l.Lang]
+ if !ok {
+ ruleFunc = trNLangRules["en-US"]
+ }
+
+ if ruleFunc(c) == 0 {
+ return l.Tr(key1, args...)
+ }
+ return l.Tr(keyN, args...)
+}
diff --git a/routers/web/repo/migrate.go b/routers/web/repo/migrate.go
index 9b1265383908e..dc9a05e0651ba 100644
--- a/routers/web/repo/migrate.go
+++ b/routers/web/repo/migrate.go
@@ -81,13 +81,8 @@ func handleMigrateError(ctx *context.Context, owner *user_model.User, err error,
case migrations.IsTwoFactorAuthError(err):
ctx.RenderWithErr(ctx.Tr("form.2fa_auth_required"), tpl, form)
case repo_model.IsErrReachLimitOfRepo(err):
- var msg string
maxCreationLimit := ctx.User.MaxCreationLimit()
- if maxCreationLimit == 1 {
- msg = ctx.Tr("repo.form.reach_limit_of_creation_1", maxCreationLimit)
- } else {
- msg = ctx.Tr("repo.form.reach_limit_of_creation_n", maxCreationLimit)
- }
+ msg := ctx.TrN(maxCreationLimit, "repo.form.reach_limit_of_creation_1", "repo.form.reach_limit_of_creation_1", maxCreationLimit)
ctx.RenderWithErr(msg, tpl, form)
case repo_model.IsErrRepoAlreadyExist(err):
ctx.Data["Err_RepoName"] = true
diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go
index 0d8c6d374f989..1d074f886394b 100644
--- a/routers/web/repo/repo.go
+++ b/routers/web/repo/repo.go
@@ -162,13 +162,8 @@ func Create(ctx *context.Context) {
func handleCreateError(ctx *context.Context, owner *user_model.User, err error, name string, tpl base.TplName, form interface{}) {
switch {
case repo_model.IsErrReachLimitOfRepo(err):
- var msg string
maxCreationLimit := ctx.User.MaxCreationLimit()
- if maxCreationLimit == 1 {
- msg = ctx.Tr("repo.form.reach_limit_of_creation_1", maxCreationLimit)
- } else {
- msg = ctx.Tr("repo.form.reach_limit_of_creation_n", maxCreationLimit)
- }
+ msg := ctx.TrN(maxCreationLimit, "repo.form.reach_limit_of_creation_1", "repo.form.reach_limit_of_creation_1", maxCreationLimit)
ctx.RenderWithErr(msg, tpl, form)
case repo_model.IsErrRepoAlreadyExist(err):
ctx.Data["Err_RepoName"] = true
diff --git a/routers/web/repo/setting.go b/routers/web/repo/setting.go
index 5457e651d38f6..9c9de2ee144cf 100644
--- a/routers/web/repo/setting.go
+++ b/routers/web/repo/setting.go
@@ -610,11 +610,8 @@ func SettingsPost(ctx *context.Context) {
if !ctx.Repo.Owner.CanCreateRepo() {
maxCreationLimit := ctx.User.MaxCreationLimit()
- if maxCreationLimit == 1 {
- ctx.Flash.Error(ctx.Tr("repo.form.reach_limit_of_creation_1", maxCreationLimit))
- } else {
- ctx.Flash.Error(ctx.Tr("repo.form.reach_limit_of_creation_n", maxCreationLimit))
- }
+ msg := ctx.TrN(maxCreationLimit, "repo.form.reach_limit_of_creation_1", "repo.form.reach_limit_of_creation_1", maxCreationLimit)
+ ctx.Flash.Error(msg)
ctx.Redirect(repo.Link() + "/settings")
return
}
diff --git a/services/mailer/mail.go b/services/mailer/mail.go
index 0a5573707396c..20552be584781 100644
--- a/services/mailer/mail.go
+++ b/services/mailer/mail.go
@@ -78,7 +78,6 @@ func sendUserMail(language string, u *user_model.User, tpl base.TplName, code, s
// helper
"i18n": locale,
"Str2html": templates.Str2html,
- "TrN": templates.TrN,
}
var content bytes.Buffer
@@ -129,7 +128,6 @@ func SendActivateEmailMail(u *user_model.User, email *user_model.EmailAddress) {
// helper
"i18n": locale,
"Str2html": templates.Str2html,
- "TrN": templates.TrN,
}
var content bytes.Buffer
@@ -160,7 +158,6 @@ func SendRegisterNotifyMail(u *user_model.User) {
// helper
"i18n": locale,
"Str2html": templates.Str2html,
- "TrN": templates.TrN,
}
var content bytes.Buffer
@@ -194,7 +191,6 @@ func SendCollaboratorMail(u, doer *user_model.User, repo *repo_model.Repository)
// helper
"i18n": locale,
"Str2html": templates.Str2html,
- "TrN": templates.TrN,
}
var content bytes.Buffer
@@ -278,7 +274,6 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient
// helper
"i18n": locale,
"Str2html": templates.Str2html,
- "TrN": templates.TrN,
}
var mailSubject bytes.Buffer
diff --git a/services/mailer/mail_release.go b/services/mailer/mail_release.go
index 02aa0f312e36f..ee4c6f3a59cd0 100644
--- a/services/mailer/mail_release.go
+++ b/services/mailer/mail_release.go
@@ -76,7 +76,6 @@ func mailNewRelease(lang string, tos []string, rel *models.Release) {
// helper
"i18n": locale,
"Str2html": templates.Str2html,
- "TrN": templates.TrN,
}
var mailBody bytes.Buffer
diff --git a/services/mailer/mail_repo.go b/services/mailer/mail_repo.go
index 51b16aa7e270f..a5343f81286e4 100644
--- a/services/mailer/mail_repo.go
+++ b/services/mailer/mail_repo.go
@@ -71,7 +71,6 @@ func sendRepoTransferNotifyMailPerLang(lang string, newOwner, doer *user_model.U
// helper
"i18n": locale,
"Str2html": templates.Str2html,
- "TrN": templates.TrN,
}
if err := bodyTemplates.ExecuteTemplate(&content, string(mailRepoTransferNotify), data); err != nil {
diff --git a/templates/mail/issue/default.tmpl b/templates/mail/issue/default.tmpl
index e01ec667eedc8..aa91861d11abc 100644
--- a/templates/mail/issue/default.tmpl
+++ b/templates/mail/issue/default.tmpl
@@ -30,7 +30,7 @@
{{.i18n.Tr "mail.issue.action.force_push" .Doer.Name .Comment.Issue.PullRequest.HeadBranch $oldCommitLink $newCommitLink | Str2html}}
{{else}}
- {{.i18n.Tr (TrN .i18n.Lang (len .Comment.Commits) "mail.issue.action.push_1" "mail.issue.action.push_n") .Doer.Name .Comment.Issue.PullRequest.HeadBranch (len .Comment.Commits) | Str2html}}
+ {{.i18n.TrN (len .Comment.Commits) "mail.issue.action.push_1" "mail.issue.action.push_n" .Doer.Name .Comment.Issue.PullRequest.HeadBranch (len .Comment.Commits) | Str2html}}
{{end}}
{{end}}
diff --git a/templates/repo/activity.tmpl b/templates/repo/activity.tmpl
index c67925e4233ca..3086ca8e8d3ce 100644
--- a/templates/repo/activity.tmpl
+++ b/templates/repo/activity.tmpl
@@ -41,7 +41,7 @@
{{end}}
- {{.i18n.Tr (TrN .i18n.Lang .Activity.ActivePRCount "repo.activity.active_prs_count_1" "repo.activity.active_prs_count_n") .Activity.ActivePRCount | Safe }}
+ {{.i18n.TrN .Activity.ActivePRCount "repo.activity.active_prs_count_1" "repo.activity.active_prs_count_n" .Activity.ActivePRCount | Safe }}
{{end}}
{{if .Permission.CanRead $.UnitTypeIssues}}
@@ -56,7 +56,7 @@
{{end}}
- {{.i18n.Tr (TrN .i18n.Lang .Activity.ActiveIssueCount "repo.activity.active_issues_count_1" "repo.activity.active_issues_count_n") .Activity.ActiveIssueCount | Safe }}
+ {{.i18n.TrN .Activity.ActiveIssueCount "repo.activity.active_issues_count_1" "repo.activity.active_issues_count_n" .Activity.ActiveIssueCount | Safe }}
{{end}}
@@ -64,21 +64,21 @@
{{if .Permission.CanRead $.UnitTypePullRequests}}
{{svg "octicon-git-pull-request"}} {{.Activity.MergedPRCount}}
- {{.i18n.Tr (TrN .i18n.Lang .Activity.MergedPRCount "repo.activity.merged_prs_count_1" "repo.activity.merged_prs_count_n") }}
+ {{.i18n.TrN .Activity.MergedPRCount "repo.activity.merged_prs_count_1" "repo.activity.merged_prs_count_n"}}
{{svg "octicon-git-branch"}} {{.Activity.OpenedPRCount}}
- {{.i18n.Tr (TrN .i18n.Lang .Activity.OpenedPRCount "repo.activity.opened_prs_count_1" "repo.activity.opened_prs_count_n") }}
+ {{.i18n.TrN .Activity.OpenedPRCount "repo.activity.opened_prs_count_1" "repo.activity.opened_prs_count_n"}}
{{end}}
{{if .Permission.CanRead $.UnitTypeIssues}}
{{svg "octicon-issue-closed"}} {{.Activity.ClosedIssueCount}}
- {{.i18n.Tr (TrN .i18n.Lang .Activity.ClosedIssueCount "repo.activity.closed_issues_count_1" "repo.activity.closed_issues_count_n") }}
+ {{.i18n.TrN .Activity.ClosedIssueCount "repo.activity.closed_issues_count_1" "repo.activity.closed_issues_count_n"}}
{{svg "octicon-issue-opened"}} {{.Activity.OpenedIssueCount}}
- {{.i18n.Tr (TrN .i18n.Lang .Activity.OpenedIssueCount "repo.activity.new_issues_count_1" "repo.activity.new_issues_count_n") }}
+ {{.i18n.TrN .Activity.OpenedIssueCount "repo.activity.new_issues_count_1" "repo.activity.new_issues_count_n"}}
{{end}}
@@ -94,19 +94,19 @@
{{.i18n.Tr "repo.activity.git_stats_exclude_merges" }}
- {{.i18n.Tr (TrN .i18n.Lang .Activity.Code.AuthorCount "repo.activity.git_stats_author_1" "repo.activity.git_stats_author_n") .Activity.Code.AuthorCount }}
- {{.i18n.Tr (TrN .i18n.Lang .Activity.Code.AuthorCount "repo.activity.git_stats_pushed_1" "repo.activity.git_stats_pushed_n") }}
- {{.i18n.Tr (TrN .i18n.Lang .Activity.Code.CommitCount "repo.activity.git_stats_commit_1" "repo.activity.git_stats_commit_n") .Activity.Code.CommitCount }}
+ {{.i18n.TrN .Activity.Code.AuthorCount "repo.activity.git_stats_author_1" "repo.activity.git_stats_author_n" .Activity.Code.AuthorCount}}
+ {{.i18n.TrN .Activity.Code.AuthorCount "repo.activity.git_stats_pushed_1" "repo.activity.git_stats_pushed_n"}}
+ {{.i18n.TrN .Activity.Code.CommitCount "repo.activity.git_stats_commit_1" "repo.activity.git_stats_commit_n" .Activity.Code.CommitCount}}
{{.i18n.Tr "repo.activity.git_stats_push_to_branch" .Repository.DefaultBranch }}
- {{.i18n.Tr (TrN .i18n.Lang .Activity.Code.CommitCountInAllBranches "repo.activity.git_stats_commit_1" "repo.activity.git_stats_commit_n") .Activity.Code.CommitCountInAllBranches }}
+ {{.i18n.TrN .Activity.Code.CommitCountInAllBranches "repo.activity.git_stats_commit_1" "repo.activity.git_stats_commit_n" .Activity.Code.CommitCountInAllBranches}}
{{.i18n.Tr "repo.activity.git_stats_push_to_all_branches" }}
{{.i18n.Tr "repo.activity.git_stats_on_default_branch" .Repository.DefaultBranch }}
- {{.i18n.Tr (TrN .i18n.Lang .Activity.Code.ChangedFiles "repo.activity.git_stats_file_1" "repo.activity.git_stats_file_n") .Activity.Code.ChangedFiles }}
- {{.i18n.Tr (TrN .i18n.Lang .Activity.Code.ChangedFiles "repo.activity.git_stats_files_changed_1" "repo.activity.git_stats_files_changed_n") }}
+ {{.i18n.TrN .Activity.Code.ChangedFiles "repo.activity.git_stats_file_1" "repo.activity.git_stats_file_n" .Activity.Code.ChangedFiles}}
+ {{.i18n.TrN .Activity.Code.ChangedFiles "repo.activity.git_stats_files_changed_1" "repo.activity.git_stats_files_changed_n"}}
{{.i18n.Tr "repo.activity.git_stats_additions" }}
- {{.i18n.Tr (TrN .i18n.Lang .Activity.Code.Additions "repo.activity.git_stats_addition_1" "repo.activity.git_stats_addition_n") .Activity.Code.Additions }}
+ {{.i18n.TrN .Activity.Code.Additions "repo.activity.git_stats_addition_1" "repo.activity.git_stats_addition_n" .Activity.Code.Additions}}
{{.i18n.Tr "repo.activity.git_stats_and_deletions" }}
- {{.i18n.Tr (TrN .i18n.Lang .Activity.Code.Deletions "repo.activity.git_stats_deletion_1" "repo.activity.git_stats_deletion_n") .Activity.Code.Deletions }}.
+ {{.i18n.TrN .Activity.Code.Deletions "repo.activity.git_stats_deletion_1" "repo.activity.git_stats_deletion_n" .Activity.Code.Deletions}}.
@@ -118,7 +118,10 @@
{{if gt .Activity.PublishedReleaseCount 0}}
{{range .Activity.PublishedReleases}}
@@ -137,7 +140,10 @@
{{if gt .Activity.MergedPRCount 0}}
{{range .Activity.MergedPRs}}
@@ -153,7 +159,10 @@
{{if gt .Activity.OpenedPRCount 0}}
{{range .Activity.OpenedPRs}}
@@ -169,7 +178,10 @@
{{if gt .Activity.ClosedIssueCount 0}}
{{range .Activity.ClosedIssues}}
@@ -185,7 +197,10 @@
{{if gt .Activity.OpenedIssueCount 0}}
{{range .Activity.OpenedIssues}}
@@ -201,7 +216,7 @@
{{if gt .Activity.UnresolvedIssueCount 0}}
{{.i18n.Tr "repo.activity.unresolved_conv_desc"}}
diff --git a/templates/repo/blame.tmpl b/templates/repo/blame.tmpl
index 0b37f41c28c41..cdd31c0eba7aa 100644
--- a/templates/repo/blame.tmpl
+++ b/templates/repo/blame.tmpl
@@ -3,7 +3,7 @@