Skip to content

Commit a4b242a

Browse files
authored
Clean up template locale usage (#27856)
After many refactoring PRs for the "locale" and "template context function", now the ".locale" is not needed for web templates any more. This PR does a clean up for: 1. Remove `ctx.Data["locale"]` for web context. 2. Use `ctx.Locale` in `500.tmpl`, for consistency. 3. Add a test check for `500 page` locale usage. 4. Remove the `Str2html` and `DotEscape` from mail template context data, they are copy&paste errors introduced by #19169 and #16200 . These functions are template functions (provided by the common renderer), but not template data variables. 5. Make email `SendAsync` function mockable (I was planning to add more tests but it would make this PR much too complex, so the tests could be done in another PR)
1 parent 16d15ce commit a4b242a

File tree

10 files changed

+33
-65
lines changed

10 files changed

+33
-65
lines changed

modules/context/context.go

-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,6 @@ func Contexter() func(next http.Handler) http.Handler {
157157
ctx.Data["Context"] = ctx // TODO: use "ctx" in template and remove this
158158
ctx.Data["CurrentURL"] = setting.AppSubURL + req.URL.RequestURI()
159159
ctx.Data["Link"] = ctx.Link
160-
ctx.Data["locale"] = ctx.Locale
161160

162161
// PageData is passed by reference, and it will be rendered to `window.config.pageData` in `head.tmpl` for JavaScript modules
163162
ctx.PageData = map[string]any{}

routers/common/errpage.go

+7-8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
user_model "code.gitea.io/gitea/models/user"
1111
"code.gitea.io/gitea/modules/base"
12+
"code.gitea.io/gitea/modules/context"
1213
"code.gitea.io/gitea/modules/httpcache"
1314
"code.gitea.io/gitea/modules/log"
1415
"code.gitea.io/gitea/modules/setting"
@@ -35,20 +36,18 @@ func RenderPanicErrorPage(w http.ResponseWriter, req *http.Request, err any) {
3536
httpcache.SetCacheControlInHeader(w.Header(), 0, "no-transform")
3637
w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions)
3738

38-
data := middleware.GetContextData(req.Context())
39-
if data["locale"] == nil {
40-
data = middleware.CommonTemplateContextData()
41-
data["locale"] = middleware.Locale(w, req)
42-
}
39+
tmplCtx := context.TemplateContext{}
40+
tmplCtx["Locale"] = middleware.Locale(w, req)
41+
ctxData := middleware.GetContextData(req.Context())
4342

4443
// This recovery handler could be called without Gitea's web context, so we shouldn't touch that context too much.
4544
// Otherwise, the 500-page may cause new panics, eg: cache.GetContextWithData, it makes the developer&users couldn't find the original panic.
46-
user, _ := data[middleware.ContextDataKeySignedUser].(*user_model.User)
45+
user, _ := ctxData[middleware.ContextDataKeySignedUser].(*user_model.User)
4746
if !setting.IsProd || (user != nil && user.IsAdmin) {
48-
data["ErrorMsg"] = "PANIC: " + combinedErr
47+
ctxData["ErrorMsg"] = "PANIC: " + combinedErr
4948
}
5049

51-
err = templates.HTMLRenderer().HTML(w, http.StatusInternalServerError, string(tplStatus500), data, nil)
50+
err = templates.HTMLRenderer().HTML(w, http.StatusInternalServerError, string(tplStatus500), ctxData, tmplCtx)
5251
if err != nil {
5352
log.Error("Error occurs again when rendering error page: %v", err)
5453
w.WriteHeader(http.StatusInternalServerError)

routers/common/errpage_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ func TestRenderPanicErrorPage(t *testing.T) {
2626
respContent := w.Body.String()
2727
assert.Contains(t, respContent, `class="page-content status-page-500"`)
2828
assert.Contains(t, respContent, `</html>`)
29+
assert.Contains(t, respContent, `lang="en-US"`) // make sure the locale work
2930

3031
// the 500 page doesn't have normal pages footer, it makes it easier to distinguish a normal page and a failed page.
3132
// especially when a sub-template causes page error, the HTTP response code is still 200,

services/mailer/mail.go

+6-22
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import (
2626
"code.gitea.io/gitea/modules/markup"
2727
"code.gitea.io/gitea/modules/markup/markdown"
2828
"code.gitea.io/gitea/modules/setting"
29-
"code.gitea.io/gitea/modules/templates"
3029
"code.gitea.io/gitea/modules/timeutil"
3130
"code.gitea.io/gitea/modules/translation"
3231
incoming_payload "code.gitea.io/gitea/services/mailer/incoming/payload"
@@ -68,15 +67,12 @@ func SendTestMail(email string) error {
6867
func sendUserMail(language string, u *user_model.User, tpl base.TplName, code, subject, info string) {
6968
locale := translation.NewLocale(language)
7069
data := map[string]any{
70+
"locale": locale,
7171
"DisplayName": u.DisplayName(),
7272
"ActiveCodeLives": timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, locale),
7373
"ResetPwdCodeLives": timeutil.MinutesToFriendly(setting.Service.ResetPwdCodeLives, locale),
7474
"Code": code,
7575
"Language": locale.Language(),
76-
// helper
77-
"locale": locale,
78-
"Str2html": templates.Str2html,
79-
"DotEscape": templates.DotEscape,
8076
}
8177

8278
var content bytes.Buffer
@@ -119,15 +115,12 @@ func SendActivateEmailMail(u *user_model.User, email *user_model.EmailAddress) {
119115
}
120116
locale := translation.NewLocale(u.Language)
121117
data := map[string]any{
118+
"locale": locale,
122119
"DisplayName": u.DisplayName(),
123120
"ActiveCodeLives": timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, locale),
124121
"Code": u.GenerateEmailActivateCode(email.Email),
125122
"Email": email.Email,
126123
"Language": locale.Language(),
127-
// helper
128-
"locale": locale,
129-
"Str2html": templates.Str2html,
130-
"DotEscape": templates.DotEscape,
131124
}
132125

133126
var content bytes.Buffer
@@ -152,13 +145,10 @@ func SendRegisterNotifyMail(u *user_model.User) {
152145
locale := translation.NewLocale(u.Language)
153146

154147
data := map[string]any{
148+
"locale": locale,
155149
"DisplayName": u.DisplayName(),
156150
"Username": u.Name,
157151
"Language": locale.Language(),
158-
// helper
159-
"locale": locale,
160-
"Str2html": templates.Str2html,
161-
"DotEscape": templates.DotEscape,
162152
}
163153

164154
var content bytes.Buffer
@@ -185,14 +175,11 @@ func SendCollaboratorMail(u, doer *user_model.User, repo *repo_model.Repository)
185175

186176
subject := locale.Tr("mail.repo.collaborator.added.subject", doer.DisplayName(), repoName)
187177
data := map[string]any{
178+
"locale": locale,
188179
"Subject": subject,
189180
"RepoName": repoName,
190181
"Link": repo.HTMLURL(),
191182
"Language": locale.Language(),
192-
// helper
193-
"locale": locale,
194-
"Str2html": templates.Str2html,
195-
"DotEscape": templates.DotEscape,
196183
}
197184

198185
var content bytes.Buffer
@@ -259,6 +246,7 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient
259246
locale := translation.NewLocale(lang)
260247

261248
mailMeta := map[string]any{
249+
"locale": locale,
262250
"FallbackSubject": fallback,
263251
"Body": body,
264252
"Link": link,
@@ -275,10 +263,6 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient
275263
"ReviewComments": reviewComments,
276264
"Language": locale.Language(),
277265
"CanReply": setting.IncomingEmail.Enabled && commentType != issues_model.CommentTypePullRequestPush,
278-
// helper
279-
"locale": locale,
280-
"Str2html": templates.Str2html,
281-
"DotEscape": templates.DotEscape,
282266
}
283267

284268
var mailSubject bytes.Buffer
@@ -469,7 +453,7 @@ func SendIssueAssignedMail(ctx context.Context, issue *issues_model.Issue, doer
469453
if err != nil {
470454
return err
471455
}
472-
SendAsyncs(msgs)
456+
SendAsync(msgs...)
473457
}
474458
return nil
475459
}

services/mailer/mail_issue.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ func mailIssueCommentBatch(ctx *mailCommentContext, users []*user_model.User, vi
162162
if err != nil {
163163
return err
164164
}
165-
SendAsyncs(msgs)
165+
SendAsync(msgs...)
166166
receivers = receivers[:i]
167167
}
168168
}

services/mailer/mail_release.go

+2-6
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import (
1414
"code.gitea.io/gitea/modules/markup"
1515
"code.gitea.io/gitea/modules/markup/markdown"
1616
"code.gitea.io/gitea/modules/setting"
17-
"code.gitea.io/gitea/modules/templates"
1817
"code.gitea.io/gitea/modules/translation"
1918
)
2019

@@ -69,13 +68,10 @@ func mailNewRelease(ctx context.Context, lang string, tos []string, rel *repo_mo
6968

7069
subject := locale.Tr("mail.release.new.subject", rel.TagName, rel.Repo.FullName())
7170
mailMeta := map[string]any{
71+
"locale": locale,
7272
"Release": rel,
7373
"Subject": subject,
7474
"Language": locale.Language(),
75-
// helper
76-
"locale": locale,
77-
"Str2html": templates.Str2html,
78-
"DotEscape": templates.DotEscape,
7975
}
8076

8177
var mailBody bytes.Buffer
@@ -95,5 +91,5 @@ func mailNewRelease(ctx context.Context, lang string, tos []string, rel *repo_mo
9591
msgs = append(msgs, msg)
9692
}
9793

98-
SendAsyncs(msgs)
94+
SendAsync(msgs...)
9995
}

services/mailer/mail_repo.go

+1-5
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
repo_model "code.gitea.io/gitea/models/repo"
1313
user_model "code.gitea.io/gitea/models/user"
1414
"code.gitea.io/gitea/modules/setting"
15-
"code.gitea.io/gitea/modules/templates"
1615
"code.gitea.io/gitea/modules/translation"
1716
)
1817

@@ -65,17 +64,14 @@ func sendRepoTransferNotifyMailPerLang(lang string, newOwner, doer *user_model.U
6564
}
6665

6766
data := map[string]any{
67+
"locale": locale,
6868
"Doer": doer,
6969
"User": repo.Owner,
7070
"Repo": repo.FullName(),
7171
"Link": repo.HTMLURL(),
7272
"Subject": subject,
7373
"Language": locale.Language(),
7474
"Destination": destination,
75-
// helper
76-
"locale": locale,
77-
"Str2html": templates.Str2html,
78-
"DotEscape": templates.DotEscape,
7975
}
8076

8177
if err := bodyTemplates.ExecuteTemplate(&content, string(mailRepoTransferNotify), data); err != nil {

services/mailer/mail_team_invite.go

+1-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import (
1414
"code.gitea.io/gitea/modules/base"
1515
"code.gitea.io/gitea/modules/log"
1616
"code.gitea.io/gitea/modules/setting"
17-
"code.gitea.io/gitea/modules/templates"
1817
"code.gitea.io/gitea/modules/translation"
1918
)
2019

@@ -53,16 +52,13 @@ func MailTeamInvite(ctx context.Context, inviter *user_model.User, team *org_mod
5352

5453
subject := locale.Tr("mail.team_invite.subject", inviter.DisplayName(), org.DisplayName())
5554
mailMeta := map[string]any{
55+
"locale": locale,
5656
"Inviter": inviter,
5757
"Organization": org,
5858
"Team": team,
5959
"Invite": invite,
6060
"Subject": subject,
6161
"InviteURL": inviteURL,
62-
// helper
63-
"locale": locale,
64-
"Str2html": templates.Str2html,
65-
"DotEscape": templates.DotEscape,
6662
}
6763

6864
var mailBody bytes.Buffer

services/mailer/mailer.go

+4-7
Original file line numberDiff line numberDiff line change
@@ -425,15 +425,12 @@ func NewContext(ctx context.Context) {
425425
go graceful.GetManager().RunWithCancel(mailQueue)
426426
}
427427

428-
// SendAsync send mail asynchronously
429-
func SendAsync(msg *Message) {
430-
SendAsyncs([]*Message{msg})
431-
}
428+
// SendAsync send emails asynchronously (make it mockable)
429+
var SendAsync = sendAsync
432430

433-
// SendAsyncs send mails asynchronously
434-
func SendAsyncs(msgs []*Message) {
431+
func sendAsync(msgs ...*Message) {
435432
if setting.MailService == nil {
436-
log.Error("Mailer: SendAsyncs is being invoked but mail service hasn't been initialized")
433+
log.Error("Mailer: SendAsync is being invoked but mail service hasn't been initialized")
437434
return
438435
}
439436

templates/status/500.tmpl

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{{/* This page should only depend the minimal template functions/variables, to avoid triggering new panics.
22
* base template functions: AppName, AssetUrlPrefix, AssetVersion, AppSubUrl, ThemeName, Str2html
3-
* locale
4-
* Flash
5-
* ErrorMsg
6-
* SignedUser (optional)
3+
* ctx.Locale
4+
* .Flash
5+
* .ErrorMsg
6+
* .SignedUser (optional)
77
*/}}
88
<!DOCTYPE html>
9-
<html lang="{{.locale.Lang}}" data-theme="{{ThemeName .SignedUser}}">
9+
<html lang="{{ctx.Locale.Lang}}" data-theme="{{ThemeName .SignedUser}}">
1010
<head>
1111
<meta name="viewport" content="width=device-width, initial-scale=1">
1212
<title>Internal Server Error - {{AppName}}</title>
@@ -19,8 +19,8 @@
1919
<nav class="ui secondary menu gt-border-secondary-bottom">
2020
<div class="ui container gt-df">
2121
<div class="item gt-f1">
22-
<a href="{{AppSubUrl}}/" aria-label="{{.locale.Tr "home"}}">
23-
<img width="30" height="30" src="{{AssetUrlPrefix}}/img/logo.svg" alt="{{.locale.Tr "logo"}}" aria-hidden="true">
22+
<a href="{{AppSubUrl}}/" aria-label="{{ctx.Locale.Tr "home"}}">
23+
<img width="30" height="30" src="{{AssetUrlPrefix}}/img/logo.svg" alt="{{ctx.Locale.Tr "logo"}}" aria-hidden="true">
2424
</a>
2525
</div>
2626
<div class="item">
@@ -37,12 +37,12 @@
3737
<div class="divider"></div>
3838
<div class="ui container gt-my-5">
3939
{{if .ErrorMsg}}
40-
<p>{{.locale.Tr "error.occurred"}}:</p>
40+
<p>{{ctx.Locale.Tr "error.occurred"}}:</p>
4141
<pre class="gt-whitespace-pre-wrap gt-break-all">{{.ErrorMsg}}</pre>
4242
{{end}}
4343
<div class="center gt-mt-5">
44-
{{if or .SignedUser.IsAdmin .ShowFooterVersion}}<p>{{.locale.Tr "admin.config.app_ver"}}: {{AppVer}}</p>{{end}}
45-
{{if .SignedUser.IsAdmin}}<p>{{.locale.Tr "error.report_message" | Str2html}}</p>{{end}}
44+
{{if or .SignedUser.IsAdmin .ShowFooterVersion}}<p>{{ctx.Locale.Tr "admin.config.app_ver"}}: {{AppVer}}</p>{{end}}
45+
{{if .SignedUser.IsAdmin}}<p>{{ctx.Locale.Tr "error.report_message" | Str2html}}</p>{{end}}
4646
</div>
4747
</div>
4848
</div>

0 commit comments

Comments
 (0)