The site's branding as email variables: its logo and its accent colour.
PhoenixKit.Email.Content.resolve/5 binds both in every part of a message
built from a file or a default — the body, _layout, _header and
_footer — so a host's files and core's own layout read the same values.
| placeholder | value |
|---|---|
{{logo_url}} | an absolute URL of the project logo, or "" |
{{accent_color}} | the email_accent_color setting as #rrggbb, or #18181b |
Both are read on every send, so a changed setting shows in the next email without a restart.
A caller may bind either variable itself; merge/2 keeps its value only
when it is valid — a #rrggbb colour, an empty or http(s):// logo URL —
and uses the site's otherwise, on every path a template can read it.
The logo
The logo is the one already set under Settings (Settings.get_logo_uuid/0:
the project logo, else the site icon). Its URL carries the permanent
signed token, so it keeps working in an email opened weeks later. A logo
stored in a private library would need a time-window token that
expires long before the email is read, so none is minted: logo_url is
empty and core's header prints the site's name instead.
A logo in the trash, or one that no longer exists, gives no URL either.
Which file of the logo
The first finished one, in this order, that every email client shows — PNG, JPEG or GIF:
small → medium → large → originalA transparent logo's JPEG-configured sizes are written as PNG
(VariantGenerator.output_format/3), or as WebP when the host sets
config :phoenix_kit, :variant_alpha_format, "webp". Outlook for Windows
shows no WebP, so a WebP size is passed over — usually for the original,
when that is a PNG. A logo with no such file (an SVG with WebP sizes, or
sizes still being made) gives no URL, and core's header prints the site's
name. Sizes made before transparent images were written as PNG are JPEG,
so such a logo arrives on a white background until its sizes are
regenerated. The URL carries the file's version, so a mail client may
cache it for good.
The accent colour
A six-digit hex colour (#1d4ed8), checked on every read: anything else —
unset, red, #abc, a value with a ; in it — reads as the neutral
default, so a bad value can never reach a style attribute.
Summary
Functions
The accent colour setting, normalised by normalize_color/1.
The settings key that holds the accent colour.
The accent colour setting as #rrggbb, or nil when it is unset or not a
valid colour — the "has the site chosen a colour?" question core's layout
asks before drawing its accent bar.
The accent colour used when none (or no valid one) is set.
An absolute URL of the project logo for an email, or "" when there is no
logo, it is in the trash or no longer exists, it sits in a private library,
it has no file every mail client shows (see "Which file of the logo"), or
the lookup fails.
variables (string keys) with the branding variables added: a caller's own
logo_url or accent_color is kept only when valid (see valid_color?/1
and valid_logo_url?/1), otherwise branding's value is used. A kept
colour is normalised.
value as a lower-case #rrggbb colour, or the default accent colour when
it is not a six-digit hex colour.
The text colour that reads on background (a colour as normalize_color/1
returns it): white on a dark colour, near-black on a light one — whichever
contrasts more, by WCAG relative luminance.
Whether value is a six-digit hex colour (surrounding whitespace allowed).
Whether value can stand as a logo URL: empty (no logo), or an absolute
http(s):// address.
Both branding variables, keyed as the templates read them.
Functions
@spec accent_color() :: String.t()
The accent colour setting, normalised by normalize_color/1.
@spec accent_color_key() :: String.t()
The settings key that holds the accent colour.
@spec configured_accent_color() :: String.t() | nil
The accent colour setting as #rrggbb, or nil when it is unset or not a
valid colour — the "has the site chosen a colour?" question core's layout
asks before drawing its accent bar.
@spec default_accent_color() :: String.t()
The accent colour used when none (or no valid one) is set.
@spec logo_url() :: String.t()
An absolute URL of the project logo for an email, or "" when there is no
logo, it is in the trash or no longer exists, it sits in a private library,
it has no file every mail client shows (see "Which file of the logo"), or
the lookup fails.
@spec merge(%{required(String.t()) => term()}, %{required(String.t()) => String.t()}) :: %{ required(String.t()) => term() }
variables (string keys) with the branding variables added: a caller's own
logo_url or accent_color is kept only when valid (see valid_color?/1
and valid_logo_url?/1), otherwise branding's value is used. A kept
colour is normalised.
value as a lower-case #rrggbb colour, or the default accent colour when
it is not a six-digit hex colour.
iex> PhoenixKit.Email.Branding.normalize_color(" #1D4ED8 ")
"#1d4ed8"
iex> PhoenixKit.Email.Branding.normalize_color("red;background:url(x)")
"#18181b"
The text colour that reads on background (a colour as normalize_color/1
returns it): white on a dark colour, near-black on a light one — whichever
contrasts more, by WCAG relative luminance.
Whether value is a six-digit hex colour (surrounding whitespace allowed).
iex> PhoenixKit.Email.Branding.valid_color?("#1d4ed8")
true
iex> PhoenixKit.Email.Branding.valid_color?("#1d4ed8;x:y")
false
Whether value can stand as a logo URL: empty (no logo), or an absolute
http(s):// address.
Both branding variables, keyed as the templates read them.