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)
This commit is contained in:
parent
16d15ce087
commit
a4b242ae7a
|
@ -157,7 +157,6 @@ func Contexter() func(next http.Handler) http.Handler {
|
|||
ctx.Data["Context"] = ctx // TODO: use "ctx" in template and remove this
|
||||
ctx.Data["CurrentURL"] = setting.AppSubURL + req.URL.RequestURI()
|
||||
ctx.Data["Link"] = ctx.Link
|
||||
ctx.Data["locale"] = ctx.Locale
|
||||
|
||||
// PageData is passed by reference, and it will be rendered to `window.config.pageData` in `head.tmpl` for JavaScript modules
|
||||
ctx.PageData = map[string]any{}
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/httpcache"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
@ -35,20 +36,18 @@ func RenderPanicErrorPage(w http.ResponseWriter, req *http.Request, err any) {
|
|||
httpcache.SetCacheControlInHeader(w.Header(), 0, "no-transform")
|
||||
w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions)
|
||||
|
||||
data := middleware.GetContextData(req.Context())
|
||||
if data["locale"] == nil {
|
||||
data = middleware.CommonTemplateContextData()
|
||||
data["locale"] = middleware.Locale(w, req)
|
||||
}
|
||||
tmplCtx := context.TemplateContext{}
|
||||
tmplCtx["Locale"] = middleware.Locale(w, req)
|
||||
ctxData := middleware.GetContextData(req.Context())
|
||||
|
||||
// This recovery handler could be called without Gitea's web context, so we shouldn't touch that context too much.
|
||||
// Otherwise, the 500-page may cause new panics, eg: cache.GetContextWithData, it makes the developer&users couldn't find the original panic.
|
||||
user, _ := data[middleware.ContextDataKeySignedUser].(*user_model.User)
|
||||
user, _ := ctxData[middleware.ContextDataKeySignedUser].(*user_model.User)
|
||||
if !setting.IsProd || (user != nil && user.IsAdmin) {
|
||||
data["ErrorMsg"] = "PANIC: " + combinedErr
|
||||
ctxData["ErrorMsg"] = "PANIC: " + combinedErr
|
||||
}
|
||||
|
||||
err = templates.HTMLRenderer().HTML(w, http.StatusInternalServerError, string(tplStatus500), data, nil)
|
||||
err = templates.HTMLRenderer().HTML(w, http.StatusInternalServerError, string(tplStatus500), ctxData, tmplCtx)
|
||||
if err != nil {
|
||||
log.Error("Error occurs again when rendering error page: %v", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
|
|
|
@ -26,6 +26,7 @@ func TestRenderPanicErrorPage(t *testing.T) {
|
|||
respContent := w.Body.String()
|
||||
assert.Contains(t, respContent, `class="page-content status-page-500"`)
|
||||
assert.Contains(t, respContent, `</html>`)
|
||||
assert.Contains(t, respContent, `lang="en-US"`) // make sure the locale work
|
||||
|
||||
// the 500 page doesn't have normal pages footer, it makes it easier to distinguish a normal page and a failed page.
|
||||
// especially when a sub-template causes page error, the HTTP response code is still 200,
|
||||
|
|
|
@ -26,7 +26,6 @@ import (
|
|||
"code.gitea.io/gitea/modules/markup"
|
||||
"code.gitea.io/gitea/modules/markup/markdown"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/templates"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/translation"
|
||||
incoming_payload "code.gitea.io/gitea/services/mailer/incoming/payload"
|
||||
|
@ -68,15 +67,12 @@ func SendTestMail(email string) error {
|
|||
func sendUserMail(language string, u *user_model.User, tpl base.TplName, code, subject, info string) {
|
||||
locale := translation.NewLocale(language)
|
||||
data := map[string]any{
|
||||
"locale": locale,
|
||||
"DisplayName": u.DisplayName(),
|
||||
"ActiveCodeLives": timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, locale),
|
||||
"ResetPwdCodeLives": timeutil.MinutesToFriendly(setting.Service.ResetPwdCodeLives, locale),
|
||||
"Code": code,
|
||||
"Language": locale.Language(),
|
||||
// helper
|
||||
"locale": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"DotEscape": templates.DotEscape,
|
||||
}
|
||||
|
||||
var content bytes.Buffer
|
||||
|
@ -119,15 +115,12 @@ func SendActivateEmailMail(u *user_model.User, email *user_model.EmailAddress) {
|
|||
}
|
||||
locale := translation.NewLocale(u.Language)
|
||||
data := map[string]any{
|
||||
"locale": locale,
|
||||
"DisplayName": u.DisplayName(),
|
||||
"ActiveCodeLives": timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, locale),
|
||||
"Code": u.GenerateEmailActivateCode(email.Email),
|
||||
"Email": email.Email,
|
||||
"Language": locale.Language(),
|
||||
// helper
|
||||
"locale": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"DotEscape": templates.DotEscape,
|
||||
}
|
||||
|
||||
var content bytes.Buffer
|
||||
|
@ -152,13 +145,10 @@ func SendRegisterNotifyMail(u *user_model.User) {
|
|||
locale := translation.NewLocale(u.Language)
|
||||
|
||||
data := map[string]any{
|
||||
"locale": locale,
|
||||
"DisplayName": u.DisplayName(),
|
||||
"Username": u.Name,
|
||||
"Language": locale.Language(),
|
||||
// helper
|
||||
"locale": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"DotEscape": templates.DotEscape,
|
||||
}
|
||||
|
||||
var content bytes.Buffer
|
||||
|
@ -185,14 +175,11 @@ func SendCollaboratorMail(u, doer *user_model.User, repo *repo_model.Repository)
|
|||
|
||||
subject := locale.Tr("mail.repo.collaborator.added.subject", doer.DisplayName(), repoName)
|
||||
data := map[string]any{
|
||||
"locale": locale,
|
||||
"Subject": subject,
|
||||
"RepoName": repoName,
|
||||
"Link": repo.HTMLURL(),
|
||||
"Language": locale.Language(),
|
||||
// helper
|
||||
"locale": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"DotEscape": templates.DotEscape,
|
||||
}
|
||||
|
||||
var content bytes.Buffer
|
||||
|
@ -259,6 +246,7 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient
|
|||
locale := translation.NewLocale(lang)
|
||||
|
||||
mailMeta := map[string]any{
|
||||
"locale": locale,
|
||||
"FallbackSubject": fallback,
|
||||
"Body": body,
|
||||
"Link": link,
|
||||
|
@ -275,10 +263,6 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient
|
|||
"ReviewComments": reviewComments,
|
||||
"Language": locale.Language(),
|
||||
"CanReply": setting.IncomingEmail.Enabled && commentType != issues_model.CommentTypePullRequestPush,
|
||||
// helper
|
||||
"locale": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"DotEscape": templates.DotEscape,
|
||||
}
|
||||
|
||||
var mailSubject bytes.Buffer
|
||||
|
@ -469,7 +453,7 @@ func SendIssueAssignedMail(ctx context.Context, issue *issues_model.Issue, doer
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
SendAsyncs(msgs)
|
||||
SendAsync(msgs...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -162,7 +162,7 @@ func mailIssueCommentBatch(ctx *mailCommentContext, users []*user_model.User, vi
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
SendAsyncs(msgs)
|
||||
SendAsync(msgs...)
|
||||
receivers = receivers[:i]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import (
|
|||
"code.gitea.io/gitea/modules/markup"
|
||||
"code.gitea.io/gitea/modules/markup/markdown"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/templates"
|
||||
"code.gitea.io/gitea/modules/translation"
|
||||
)
|
||||
|
||||
|
@ -69,13 +68,10 @@ func mailNewRelease(ctx context.Context, lang string, tos []string, rel *repo_mo
|
|||
|
||||
subject := locale.Tr("mail.release.new.subject", rel.TagName, rel.Repo.FullName())
|
||||
mailMeta := map[string]any{
|
||||
"locale": locale,
|
||||
"Release": rel,
|
||||
"Subject": subject,
|
||||
"Language": locale.Language(),
|
||||
// helper
|
||||
"locale": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"DotEscape": templates.DotEscape,
|
||||
}
|
||||
|
||||
var mailBody bytes.Buffer
|
||||
|
@ -95,5 +91,5 @@ func mailNewRelease(ctx context.Context, lang string, tos []string, rel *repo_mo
|
|||
msgs = append(msgs, msg)
|
||||
}
|
||||
|
||||
SendAsyncs(msgs)
|
||||
SendAsync(msgs...)
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/templates"
|
||||
"code.gitea.io/gitea/modules/translation"
|
||||
)
|
||||
|
||||
|
@ -65,6 +64,7 @@ func sendRepoTransferNotifyMailPerLang(lang string, newOwner, doer *user_model.U
|
|||
}
|
||||
|
||||
data := map[string]any{
|
||||
"locale": locale,
|
||||
"Doer": doer,
|
||||
"User": repo.Owner,
|
||||
"Repo": repo.FullName(),
|
||||
|
@ -72,10 +72,6 @@ func sendRepoTransferNotifyMailPerLang(lang string, newOwner, doer *user_model.U
|
|||
"Subject": subject,
|
||||
"Language": locale.Language(),
|
||||
"Destination": destination,
|
||||
// helper
|
||||
"locale": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"DotEscape": templates.DotEscape,
|
||||
}
|
||||
|
||||
if err := bodyTemplates.ExecuteTemplate(&content, string(mailRepoTransferNotify), data); err != nil {
|
||||
|
|
|
@ -14,7 +14,6 @@ import (
|
|||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/templates"
|
||||
"code.gitea.io/gitea/modules/translation"
|
||||
)
|
||||
|
||||
|
@ -53,16 +52,13 @@ func MailTeamInvite(ctx context.Context, inviter *user_model.User, team *org_mod
|
|||
|
||||
subject := locale.Tr("mail.team_invite.subject", inviter.DisplayName(), org.DisplayName())
|
||||
mailMeta := map[string]any{
|
||||
"locale": locale,
|
||||
"Inviter": inviter,
|
||||
"Organization": org,
|
||||
"Team": team,
|
||||
"Invite": invite,
|
||||
"Subject": subject,
|
||||
"InviteURL": inviteURL,
|
||||
// helper
|
||||
"locale": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"DotEscape": templates.DotEscape,
|
||||
}
|
||||
|
||||
var mailBody bytes.Buffer
|
||||
|
|
|
@ -425,15 +425,12 @@ func NewContext(ctx context.Context) {
|
|||
go graceful.GetManager().RunWithCancel(mailQueue)
|
||||
}
|
||||
|
||||
// SendAsync send mail asynchronously
|
||||
func SendAsync(msg *Message) {
|
||||
SendAsyncs([]*Message{msg})
|
||||
}
|
||||
// SendAsync send emails asynchronously (make it mockable)
|
||||
var SendAsync = sendAsync
|
||||
|
||||
// SendAsyncs send mails asynchronously
|
||||
func SendAsyncs(msgs []*Message) {
|
||||
func sendAsync(msgs ...*Message) {
|
||||
if setting.MailService == nil {
|
||||
log.Error("Mailer: SendAsyncs is being invoked but mail service hasn't been initialized")
|
||||
log.Error("Mailer: SendAsync is being invoked but mail service hasn't been initialized")
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
{{/* This page should only depend the minimal template functions/variables, to avoid triggering new panics.
|
||||
* base template functions: AppName, AssetUrlPrefix, AssetVersion, AppSubUrl, ThemeName, Str2html
|
||||
* locale
|
||||
* Flash
|
||||
* ErrorMsg
|
||||
* SignedUser (optional)
|
||||
* ctx.Locale
|
||||
* .Flash
|
||||
* .ErrorMsg
|
||||
* .SignedUser (optional)
|
||||
*/}}
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{.locale.Lang}}" data-theme="{{ThemeName .SignedUser}}">
|
||||
<html lang="{{ctx.Locale.Lang}}" data-theme="{{ThemeName .SignedUser}}">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Internal Server Error - {{AppName}}</title>
|
||||
|
@ -19,8 +19,8 @@
|
|||
<nav class="ui secondary menu gt-border-secondary-bottom">
|
||||
<div class="ui container gt-df">
|
||||
<div class="item gt-f1">
|
||||
<a href="{{AppSubUrl}}/" aria-label="{{.locale.Tr "home"}}">
|
||||
<img width="30" height="30" src="{{AssetUrlPrefix}}/img/logo.svg" alt="{{.locale.Tr "logo"}}" aria-hidden="true">
|
||||
<a href="{{AppSubUrl}}/" aria-label="{{ctx.Locale.Tr "home"}}">
|
||||
<img width="30" height="30" src="{{AssetUrlPrefix}}/img/logo.svg" alt="{{ctx.Locale.Tr "logo"}}" aria-hidden="true">
|
||||
</a>
|
||||
</div>
|
||||
<div class="item">
|
||||
|
@ -37,12 +37,12 @@
|
|||
<div class="divider"></div>
|
||||
<div class="ui container gt-my-5">
|
||||
{{if .ErrorMsg}}
|
||||
<p>{{.locale.Tr "error.occurred"}}:</p>
|
||||
<p>{{ctx.Locale.Tr "error.occurred"}}:</p>
|
||||
<pre class="gt-whitespace-pre-wrap gt-break-all">{{.ErrorMsg}}</pre>
|
||||
{{end}}
|
||||
<div class="center gt-mt-5">
|
||||
{{if or .SignedUser.IsAdmin .ShowFooterVersion}}<p>{{.locale.Tr "admin.config.app_ver"}}: {{AppVer}}</p>{{end}}
|
||||
{{if .SignedUser.IsAdmin}}<p>{{.locale.Tr "error.report_message" | Str2html}}</p>{{end}}
|
||||
{{if or .SignedUser.IsAdmin .ShowFooterVersion}}<p>{{ctx.Locale.Tr "admin.config.app_ver"}}: {{AppVer}}</p>{{end}}
|
||||
{{if .SignedUser.IsAdmin}}<p>{{ctx.Locale.Tr "error.report_message" | Str2html}}</p>{{end}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue