Skip to main content

Crate cratefield_mail_templates

Crate cratefield_mail_templates 

Source
Expand description

Branded transactional mail for Cratefield ventures: one email-client-safe layout, themed with the venture’s own website colours, logo and fonts, and a plain-text twin for every message.

Two parts:

  • MailTheme — brand name, wordmark, hosted logo and alt text, light and dark Palettes, font stacks, footer lines. Modules get it from the venture’s composition (themed_templates(&theme) on each mail-sending module), the deployment’s MAIL_THEME config (merged on top), or — with neither — MailTheme::for_venture, a neutral theme built from the venture’s name, public URL and core Brand.
  • Message — a builder for one mail: heading, paragraphs, facts, a primary button with its fallback link, a code value, notes and the footer. Message::render returns an Email with the HTML and the text part.
use cratefield_mail_templates::{MailTheme, Message};

let theme = MailTheme::new("Acme", "https://acme.test");
let email = Message::new("Sign in to Acme", "Sign in to Acme")
    .preheader("This link works once, for 15 minutes.")
    .paragraph("Use the button below to sign in.")
    .button("Sign in", "https://api.acme.test/v1/auth-magic-link/consume?token=abc")
    .fallback_link()
    .note("If you didn't ask for this, ignore this email.")
    .recipient("ada@example.com")
    .why("someone asked to sign in to Acme with this address")
    .render(&theme);
assert!(email.html.contains("consume?token=abc"));
assert!(email.text.contains("consume?token=abc"));

Email-client safety. Table layout, every style inline (the single <style> block only adds the narrow-screen and prefers-color-scheme: dark overrides, which clients without <style> support skip), no web fonts, no tracking pixel, no click tracking, lang and dir on the document. The only image is the theme’s hosted logo, with alt text; the layout reads the same without it.

Escaping. Every value — the builder’s text, the theme’s strings and anything a person typed — reaches the HTML through escape, and the text part with control characters removed, so no value can add markup or forge a line. Theme colours and fonts are checked before they reach a style attribute, and only https:, http: and mailto: URLs become links.

Structs§

Email
One rendered mail.
MailTheme
How a venture’s mail looks: its name and logo, its website’s colours in light and dark, its fonts and its footer.
Message
One mail, built up and then rendered with a theme.
Palette
One colour scheme. Every value is a CSS hex colour (#rgb, #rrggbb or #rrggbbaa); anything else is replaced by the neutral default when the mail is rendered, so a theme from config can never inject CSS.

Enums§

Dir
Text direction of the mail.

Constants§

DATA_THEME
The key under which a module puts the resolved theme into the data a mail template receives, so a venture’s own override template can use it too.
DATA_THEME_OVERRIDE
The key under which a module puts the raw THEME_CONFIG_KEY object, so a template that carries a composed theme still applies the deployment’s adjustments on top of it.
THEME_CONFIG_KEY
The config key a deployment sets to adjust the theme without a rebuild: a JSON object with any subset of MailTheme’s fields, merged over the composed theme (nested light/dark objects merge field by field).

Functions§

attach_theme
Puts the theme a module resolved from its context into a template’s data: MailTheme::from_config under DATA_THEME, and the raw THEME_CONFIG_KEY object, when set, under DATA_THEME_OVERRIDE. data that is not an object is left alone.
escape
Escapes text for HTML element content and quoted attribute values. Control characters become spaces.
is_linkable
Whether url may be a link: https:, http: or mailto:. Anything else (javascript:, data:, a relative path that means nothing in an inbox) is shown as text instead.
plain
A value for the text part or a header: control characters (a newline in a name, say) become spaces, so no value can forge a line.
samples
Representative messages with sample values: what render-emails writes for a theme and what the snapshots cover.
theme_for_template
The theme a template renders with: the theme it was composed with (themed_templates(&theme) in each module) with the deployment’s override applied, else the theme the module attached to data, else the neutral default.