Documentation
¶
Overview ¶
Package emailtmpl renders outbound transactional email (subject + HTML + plaintext) from per-language templates embedded at build time.
It is the i18n surface for email *bodies*, parallel to — but deliberately independent of — pkg/i18n's error-code localizer. The code localizer (codes.Register + Localizer.Translate) carries single-line, parameterized error messages keyed by `err.(shared|server).*`; multi-line HTML email is a different shape and intentionally uses its own embedded template tree rather than being forced through that registry.
Each logical email is three sibling files under templates/{lang}/:
{key}.subject.tmpl — text/template (plain header, NOT html-escaped)
{key}.html.tmpl — html/template (auto-escaped, XSS-safe)
{key}.text.tmpl — text/template (plaintext alternative part)
subject/text use text/template and html uses html/template on purpose: rendering a Subject header through html/template would turn "A & B" into "A & B"; rendering HTML through text/template would drop XSS escaping on user-controlled fields (inviter name, space name, ...).
Index ¶
Constants ¶
const ( KeyVerifyCode = "verify_code" KeySpaceInviteOwner = "space_invite_owner" KeySpaceInviteMember = "space_invite_member" )
Message keys — one per logical email. Kept as constants so call sites and the template tree cannot silently drift.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Rendered ¶
Rendered is the output of Render: the three parts a transactional email needs. Subject is trimmed (no stray trailing newline leaking into the SMTP header); HTML and Text are emitted verbatim.
func Render ¶
Render produces the subject/HTML/text for a message key in the requested language. lang is normalized to the supported matrix; an unsupported/missing language falls back to fallbackLanguage. Call sites that have no per-recipient signal should pass i18n.OutboundLanguage(ctx), which already resolves to OCTO_DEFAULT_LANGUAGE.
type SpaceInviteMemberData ¶
type SpaceInviteMemberData struct {
InviterName string
SpaceName string
IsAdmin bool
AcceptURL htmltemplate.URL
}
SpaceInviteMemberData drives the space_invite_member template. IsAdmin selects the localized role label inside the template (was a hardcoded "成员"/"管理员" branch in Go).
type SpaceInviteOwnerData ¶
type SpaceInviteOwnerData struct {
InviterName string
PlannedName string
PlannedDesc string
AcceptURL htmltemplate.URL
}
SpaceInviteOwnerData drives the space_invite_owner template. An empty InviterName is handled inside the template (localized "Octo admin" fallback) so the fallback text itself is translated rather than hardcoded in Go. AcceptURL is template.URL so html/template treats the already-escaped link as a safe URL instead of re-filtering it.
type VerifyCodeData ¶
type VerifyCodeData struct {
Code string
}
VerifyCodeData drives the verify_code template.