enhance: improve e-mail templates (#38396)

Co-authored-by: bircni <bircni@icloud.com>
This commit is contained in:
silverwind
2026-09-09 19:58:27 +02:00
committed by GitHub
parent 92f2f6161b
commit 81dee529ed
43 changed files with 561 additions and 319 deletions

View File

@@ -12,10 +12,13 @@
<div class="tw-my-2">
<div>Preview of: {{.RenderMailTemplateName}}</div>
<div>Subject: {{.RenderMailSubject}}</div>
<iframe src="{{AppSubUrl}}/devtest/mail-preview/{{.RenderMailTemplateName}}" class="mail-preview-body"></iframe>
<div class="tw-flex tw-gap-4 tw-mt-2">
<iframe title="Light mail preview" src="{{AppSubUrl}}/devtest/mail-preview/{{.RenderMailTemplateName}}?scheme=light" class="mail-preview-body"></iframe>
<iframe title="Dark mail preview" src="{{AppSubUrl}}/devtest/mail-preview/{{.RenderMailTemplateName}}?scheme=dark" class="mail-preview-body"></iframe>
</div>
<style>
.mail-preview-body {
border: 1px solid #ccc;
border: 1px solid var(--color-secondary);
width: 100%;
height: 400px;
overflow: auto;

View File

@@ -0,0 +1,10 @@
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" class="mail-footer" style="width: 100%; border-collapse: collapse;">
<tr>
<td height="16" style="height: 16px; font-size: 0; line-height: 0;">&nbsp;</td>
</tr>
<tr>
<td align="center" style="border-top: 1px solid #d0d7de; color: #59636e; font-size: 12px; padding: 8px 0 0; text-align: center;">
<a href="{{AppUrl}}">{{AppName}}</a>
</td>
</tr>
</table>

View File

@@ -0,0 +1,17 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="format-detection" content="telephone=no,date=no,address=no,email=no,url=no">
<meta name="color-scheme" content="light dark">
<meta name="supported-color-schemes" content="light dark">
<title>{{.}}</title>
<style>
body {margin: 0; padding: 0}
body, td {font-family: -apple-system, "Segoe UI", system-ui, Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif}
a, a:visited {color: #0969da; text-decoration: none}
a:hover {text-decoration: underline}
blockquote {padding-left: 1em; margin: 1em 0; border-left: 1px solid grey}
@media (prefers-color-scheme: dark) {
a, a:visited {color: #58a6ff}
.mail-footer td {border-top-color: #3f4248 !important; color: #8c959f !important}
}
</style>

View File

@@ -1,3 +1,5 @@
Subject: Inviter Display Name has invited you to join the Organization Display Name organization
Inviter:
DisplayName: Inviter Display Name

View File

@@ -1,15 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="format-detection" content="telephone=no,date=no,address=no,email=no,url=no">
{{template "mail/base/head" .Subject}}
</head>
<body>
<p>{{.locale.Tr "mail.team_invite.text_1" (DotEscape .Inviter.DisplayName) (DotEscape .Team.Name) (DotEscape .Organization.DisplayName)}}</p>
<p>{{.locale.Tr "mail.team_invite.text_2"}}</p><p><a href="{{.InviteURL}}">{{.InviteURL}}</a></p>
<p>{{.locale.Tr "mail.team_invite.text_2"}}</p><p style="word-break: break-all;"><a href="{{.InviteURL}}">{{.InviteURL}}</a></p>
<p>{{.locale.Tr "mail.link_not_working_do_paste"}}</p>
<p>{{.locale.Tr "mail.team_invite.text_3" .Invite.Email}}</p>
<p>© <a href="{{AppUrl}}">{{AppName}}</a></p>
{{template "mail/base/footer"}}
</body>
</html>

View File

@@ -1,20 +1,34 @@
RunStatusText: Jobs status aggregation
Repo:
FullName: Repo/Name
Subject: "[user/repo] Failure: workflow.yml (main - 1234567890)"
Run:
WorkflowID: workflow.yml
HTMLURL: http://localhost/run/1
Jobs:
- Name: Job-Name-1
Status: success
- Name: Build and test on Ubuntu with PostgreSQL and object storage
StatusIconCID: status-success.png
StatusIconAlt: Success
StatusClass: status-success
Attempt: 1
Duration: 1m23s
HTMLURL: http://localhost/job/1
Duration: 1h2m3s
- Name: Job-Name-2
Status: failure
- Name: Lint backend, frontend, templates, styles, and documentation
StatusIconCID: status-failure.png
StatusIconAlt: Failure
StatusClass: status-failure
Attempt: 2
Duration: 2m34s
HTMLURL: http://localhost/job/2
Duration: 1h2m3s
- Name: Publish release artifacts for Linux, macOS, and Windows
StatusIconCID: status-cancelled.png
StatusIconAlt: Cancelled
StatusClass: status-neutral
Attempt: 1
Duration: 3m45s
HTMLURL: http://localhost/job/3
- Name: Deploy documentation preview to the staging environment
StatusIconCID: status-skipped.png
StatusIconAlt: Skipped
StatusClass: status-neutral
Attempt: 1
Duration: 0s
HTMLURL: http://localhost/job/4

View File

@@ -1,33 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="format-detection" content="telephone=no,date=no,address=no,email=no,url=no">
<title>{{.Subject}}</title>
{{template "mail/base/head" .Subject}}
<style>
.job-row td {border-top: 1px solid #d0d7de}
a.status-success {color: #2da44e !important}
a.status-failure {color: #e5534b !important}
a.status-neutral, .job-duration {color: #697077 !important}
img.status-neutral {filter: brightness(75%)}
@media (prefers-color-scheme: dark) {
.job-row td {border-top-color: #3f4248}
a.status-neutral, .job-duration {color: #afbac7 !important}
img.status-neutral {filter: brightness(125%)}
}
</style>
</head>
<body style="background-color: #f5f7fa; margin: 20px;">
<body>
<h2 style="color: #2c3e50; margin-bottom: 20px;">
{{.Repo.FullName}} {{.Run.WorkflowID}}: {{.RunStatusText}}
</h2>
<ul style="list-style: none; padding: 0; margin: 0 0 30px 0;">
{{range $job := .Jobs}}
<li style="background-color: #ffffff; border: 1px solid #ddd; border-radius: 6px; padding: 12px 16px; margin-bottom: 10px; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); transition: box-shadow 0.2s ease;">
<a href="{{$job.HTMLURL}}" style="color: #0073e6; text-decoration: none; font-weight: bold;">
{{$job.Status}}: {{$job.Name}}{{if gt $job.Attempt 1}}, Attempt #{{$job.Attempt}}{{end}}, {{$job.Duration}}
</a>
</li>
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="width: 100%; border-collapse: collapse;"><tr><td style="padding: 0 8px;">
{{if .Jobs}}
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="width: 100%; border-collapse: collapse;">
{{range $index, $job := .Jobs}}
<tr{{if $index}} class="job-row"{{end}}>
<td width="26" style="width: 26px; padding: 6px 8px 6px 0; vertical-align: middle;"><img class="{{$job.StatusClass}}" src="cid:{{$job.StatusIconCID}}" width="18" height="18" alt="{{$job.StatusIconAlt}}" style="display: block;"></td>
<td align="left" style="padding: 6px 0; text-align: left; vertical-align: middle; word-break: break-word;">
<a class="{{$job.StatusClass}}" href="{{$job.HTMLURL}}" style="font-weight: bold;"><span style="display: none;">{{$job.StatusIconAlt}}: </span>{{$job.Name}}</a>
{{if gt $job.Attempt 1}}({{$.locale.Tr "actions.runs.attempt"}} #{{$job.Attempt}}){{end}}
</td>
<td class="job-duration" width="1%" align="right" style="width: 1%; padding: 6px 0 6px 8px; text-align: right; vertical-align: middle; white-space: nowrap;">{{$job.Duration}}<span style="display: none;"><br></span></td>
</tr>
{{end}}
</ul>
</table>
{{else}}
<p><a href="{{.Run.HTMLURL}}">{{.Run.WorkflowID}}</a></p>
{{end}}
</td></tr></table>
<br/>
<div style="text-align: center; margin-top: 30px;">
<a href="{{.Run.HTMLURL}}" style="display: inline-block; background-color: #28a745; color: #ffffff !important; text-decoration: none; padding: 10px 20px; border-radius: 5px; font-weight: bold; box-shadow: 0 2px 4px rgba(0,0,0,0.1); transition: background-color 0.3s ease;">
{{.locale.Tr "mail.view_it_on" AppName}}
</a>
</div>
{{template "mail/base/footer"}}
</body>
</html>

View File

@@ -1,3 +1,3 @@
Subject: Collaborator added
Subject: DoerName added you to user/repo
Link: http://localhost
RepoName: Repo/Name
RepoName: user/repo

View File

@@ -1,18 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>{{.Subject}}</title>
{{template "mail/base/head" .Subject}}
</head>
<body>
<p>{{.locale.Tr "mail.repo.collaborator.added.text"}} <code>{{.RepoName}}</code></p>
<div style="font-size:small; color:#666;">
<p>
---
<br>
<a href="{{.Link}}">{{.locale.Tr "mail.view_it_on" AppName}}</a>.
</p>
</div>
<p>{{.locale.Tr "mail.repo.collaborator.added.text"}} <a href="{{.Link}}">{{.RepoName}}</a></p>
{{template "mail/base/footer"}}
</body>
</html>

View File

@@ -1,10 +1,10 @@
Subject: Issue assigned
Subject: "[user/repo] Issue Title (#1)"
Link: http://localhost
Issue:
Index: 1
Repo:
FullName: Repo/Name
FullName: user/repo
HTMLURL: http://localhost/issue
Doer:

View File

@@ -1,8 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>{{.Subject}}</title>
{{template "mail/base/head" .Subject}}
</head>
{{$repo_url := HTMLFormat "<a href='%s'>%s</a>" .Issue.Repo.HTMLURL .Issue.Repo.FullName}}
@@ -15,12 +14,7 @@
{{.locale.Tr "mail.issue_assigned.issue" .Doer.Name $link $repo_url}}
{{end}}
</p>
<div style="font-size:small; color:#666;">
<p>
---
<br>
<a href="{{.Link}}">{{.locale.Tr "mail.view_it_on" AppName}}</a>.
</p>
</div>
{{if .CanReply}}<p>{{.locale.Tr "mail.reply_directly"}}.</p>{{end}}
{{template "mail/base/footer"}}
</body>
</html>

View File

@@ -1 +1,7 @@
Subject: "Re: [user/repo] Issue Title (#1)"
Link: http://localhost/issue/1
CanReply: true
Body: Issue body
Issue:
Index: 1

View File

@@ -1,13 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>{{.Subject}}</title>
<style>
blockquote { padding-left: 1em; margin: 1em 0; border-left: 1px solid grey; color: #777}
</style>
{{template "mail/base/head" .Subject}}
</head>
<body>
@@ -75,12 +69,7 @@
{{end}}
</ul>
{{end}}
<div style="font-size:small; color:#666;">
<p>
---
<br>
<a href="{{.Link}}">{{.locale.Tr "mail.view_it_on" AppName}}</a>{{if .CanReply}}&nbsp;{{.locale.Tr "mail.reply"}}{{end}}.
</p>
</div>
<p><a href="{{.Link}}">#{{.Issue.Index}}</a>{{if .CanReply}} {{.locale.Tr "mail.reply"}}{{end}}.</p>
{{template "mail/base/footer"}}
</body>
</html>

View File

@@ -0,0 +1,13 @@
Subject: v1.0.0 in user/repo released
# no Attachments mock because "FileSize" requires int64 which yaml cannot produce
Release:
TagName: v1.0.0
Title: v1.0.0 - Great Release
HTMLURL: http://localhost/user/repo/releases/tag/v1.0.0
RenderedNote: This release fixes several bugs and improves performance.
Publisher:
Name: PublisherName
Repo:
FullName: user/repo
HTMLURL: http://localhost/user/repo

View File

@@ -1,13 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>{{.Subject}}</title>
<style>
blockquote { padding-left: 1em; margin: 1em 0; border-left: 1px solid grey; color: #777}
</style>
{{template "mail/base/head" .Subject}}
</head>
{{$release_url := HTMLFormat "<a href='%s'>%s</a>" .Release.HTMLURL .Release.TagName}}
@@ -17,18 +11,9 @@
{{.locale.Tr "mail.release.new.text" .Release.Publisher.Name $release_url $repo_url}}
</p>
<h4>{{.locale.Tr "mail.release.title" .Release.Title}}</h4>
<p>
{{.locale.Tr "mail.release.note"}}<br>
{{- if eq .Release.RenderedNote ""}}
{{else}}
{{.Release.RenderedNote}}
{{end -}}
</p>
<p style="margin-top: 2em;">
---
<br>
{{.locale.Tr "mail.release.downloads"}}
</p>
<p>{{.locale.Tr "mail.release.note"}}</p>
{{if ne .Release.RenderedNote ""}}<div>{{.Release.RenderedNote}}</div>{{end}}
<p>{{.locale.Tr "mail.release.downloads"}}</p>
<ul>
{{if not .DisableDownloadSourceArchives}}
<li>
@@ -38,22 +23,12 @@
<a href="{{.Release.Repo.HTMLURL}}/archive/{{.Release.TagName | PathEscapeSegments}}.tar.gz" rel="nofollow"><strong>{{.locale.Tr "mail.release.download.targz"}}</strong></a>
</li>
{{end}}
{{if .Release.Attachments}}
{{range .Release.Attachments}}
<li>
<a target="_blank" href="{{.DownloadURL}}">
<strong>{{.Name}} ({{.Size | FormatByteSize}})</strong>
</a>
</li>
{{end}}
{{range .Release.Attachments}}
<li>
<a target="_blank" href="{{.DownloadURL}}"><strong>{{.Name}} ({{.Size | FormatByteSize}})</strong></a>
</li>
{{end}}
</ul>
<div style="font-size:small; color:#666;">
<p>
---
<br>
<a href="{{.Link}}">{{.locale.Tr "mail.view_it_on" AppName}}</a>.
</p>
</div>
{{template "mail/base/footer"}}
</body>
</html>

View File

@@ -1,3 +1,3 @@
Subject: Repository transfer
Subject: DoerName would like to transfer "user/repo" to you
Link: http://localhost
Repo: Repo/Name
Repo: user/repo

View File

@@ -1,8 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>{{.Subject}}</title>
{{template "mail/base/head" .Subject}}
</head>
{{$url := HTMLFormat "<a href='%[1]s'>%[2]s</a>" .Link .Repo}}
@@ -10,12 +9,6 @@
<p>{{.Subject}}.
{{.locale.Tr "mail.repo.transfer.body" $url}}
</p>
<div style="font-size:small; color:#666;">
<p>
---
<br>
<a href="{{.Link}}">{{.locale.Tr "mail.view_it_on" AppName}}</a>.
</p>
</div>
{{template "mail/base/footer"}}
</body>
</html>

View File

@@ -1,3 +1,4 @@
Subject: Please activate your account
DisplayName: User Display Name
Code: The-Activation-Code
ActiveCodeLives: 24h

View File

@@ -1,17 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="format-detection" content="telephone=no,date=no,address=no,email=no,url=no">
<title>{{.locale.Tr "mail.activate_account.title" (.DisplayName|DotEscape)}}</title>
{{template "mail/base/head" (.locale.Tr "mail.activate_account.title" (.DisplayName|DotEscape))}}
</head>
{{$activate_url := printf "%suser/activate?code=%s" AppUrl (QueryEscape .Code)}}
<body>
<p>{{.locale.Tr "mail.activate_account.text_1" (.DisplayName|DotEscape) AppName}}</p><br>
<p>{{.locale.Tr "mail.activate_account.text_2" .ActiveCodeLives}}</p><p><a href="{{$activate_url}}">{{$activate_url}}</a></p><br>
<p>{{.locale.Tr "mail.activate_account.text_1" (.DisplayName|DotEscape) AppName}}</p>
<p>{{.locale.Tr "mail.activate_account.text_2" .ActiveCodeLives}}</p><p style="word-break: break-all;"><a href="{{$activate_url}}">{{$activate_url}}</a></p>
<p>{{.locale.Tr "mail.link_not_working_do_paste"}}</p>
<p>© <a href="{{AppUrl}}">{{AppName}}</a></p>
{{template "mail/base/footer"}}
</body>
</html>

View File

@@ -1,3 +1,4 @@
Subject: Verify your email address
DisplayName: User Display Name
Code: The-Activation-Code
Email: admin@example.com

View File

@@ -1,17 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta Name="format-detection" content="telephone=no,date=no,address=no,email=no,url=no">
<title>{{.locale.Tr "mail.activate_email.title" (.DisplayName|DotEscape)}}</title>
{{template "mail/base/head" (.locale.Tr "mail.activate_email.title" (.DisplayName|DotEscape))}}
</head>
{{$activate_url := printf "%suser/activate_email?code=%s&email=%s" AppUrl (QueryEscape .Code) (QueryEscape .Email)}}
<body>
<p>{{.locale.Tr "mail.hi_user_x" (.DisplayName|DotEscape)}}</p><br>
<p>{{.locale.Tr "mail.activate_email.text" .ActiveCodeLives}}</p><p><a href="{{$activate_url}}">{{$activate_url}}</a></p><br>
<p>{{.locale.Tr "mail.hi_user_x" (.DisplayName|DotEscape)}}</p>
<p>{{.locale.Tr "mail.activate_email.text" .ActiveCodeLives}}</p><p style="word-break: break-all;"><a href="{{$activate_url}}">{{$activate_url}}</a></p>
<p>{{.locale.Tr "mail.link_not_working_do_paste"}}</p>
<p>© <a href="{{AppUrl}}">{{AppName}}</a></p>
{{template "mail/base/footer"}}
</body>
</html>

View File

@@ -1,2 +1,3 @@
Subject: Welcome to Gitea
DisplayName: User Display Name
Username: Username

View File

@@ -1,18 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="format-detection" content="telephone=no,date=no,address=no,email=no,url=no">
<title>{{.locale.Tr "mail.register_notify.title" (.DisplayName|DotEscape) AppName}}</title>
{{template "mail/base/head" (.locale.Tr "mail.register_notify.title" (.DisplayName|DotEscape) AppName)}}
</head>
{{$set_pwd_url := printf "%[1]suser/forgot_password" AppUrl}}
<body>
<p>{{.locale.Tr "mail.hi_user_x" (.DisplayName|DotEscape)}}</p><br>
<p>{{.locale.Tr "mail.register_notify.text_1" AppName}}</p><br>
<p>{{.locale.Tr "mail.register_notify.text_2" .Username}}</p><p><a href="{{AppUrl}}user/login">{{AppUrl}}user/login</a></p><br>
<p>{{.locale.Tr "mail.register_notify.text_3" $set_pwd_url}}</p><br>
<p>{{.locale.Tr "mail.hi_user_x" (.DisplayName|DotEscape)}}</p>
<p>{{.locale.Tr "mail.register_notify.text_1" AppName}}</p>
<p>{{.locale.Tr "mail.register_notify.text_2" .Username}}</p><p><a href="{{AppUrl}}user/login">{{AppUrl}}user/login</a></p>
<p>{{.locale.Tr "mail.register_notify.text_3" $set_pwd_url}}</p>
<p>© <a href="{{AppUrl}}">{{AppName}}</a></p>
{{template "mail/base/footer"}}
</body>
</html>

View File

@@ -1,3 +1,4 @@
Subject: Recover your account
DisplayName: User Display Name
Code: The-Reset-Token
ResetPwdCodeLives: 24h

View File

@@ -1,17 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="format-detection" content="telephone=no,date=no,address=no,email=no,url=no">
<title>{{.locale.Tr "mail.reset_password.title" (.DisplayName|DotEscape)}}</title>
{{template "mail/base/head" (.locale.Tr "mail.reset_password.title" (.DisplayName|DotEscape))}}
</head>
{{$recover_url := printf "%suser/recover_account?code=%s" AppUrl (QueryEscape .Code)}}
<body>
<p>{{.locale.Tr "mail.hi_user_x" (.DisplayName|DotEscape)}}</p><br>
<p>{{.locale.Tr "mail.reset_password.text" .ResetPwdCodeLives}}</p><p><a href="{{$recover_url}}">{{$recover_url}}</a></p><br>
<p>{{.locale.Tr "mail.hi_user_x" (.DisplayName|DotEscape)}}</p>
<p>{{.locale.Tr "mail.reset_password.text" .ResetPwdCodeLives}}</p><p style="word-break: break-all;"><a href="{{$recover_url}}">{{$recover_url}}</a></p>
<p>{{.locale.Tr "mail.link_not_working_do_paste"}}</p>
<p>© <a href="{{AppUrl}}">{{AppName}}</a></p>
{{template "mail/base/footer"}}
</body>
</html>