add logo to newsletter email header
All checks were successful
deploy / deploy (push) Successful in 1m4s
All checks were successful
deploy / deploy (push) Successful in 1m4s
Uses the shop logo image if configured, falls back to the favicon icon (served as PNG) alongside the shop name, or plain text if neither is available. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c71d08bb5c
commit
aa008f83b2
@ -121,9 +121,10 @@ defmodule Berrypod.Newsletter.Notifier do
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Wraps HTML content in a branded email template.
|
# Wraps HTML content in a branded email template.
|
||||||
# Keeps it simple: single column, shop name header, optional unsubscribe footer.
|
# Keeps it simple: single column, logo/shop name header, optional unsubscribe footer.
|
||||||
@doc false
|
@doc false
|
||||||
def wrap_html(shop_name, content, unsubscribe_url \\ nil) do
|
def wrap_html(shop_name, content, unsubscribe_url \\ nil) do
|
||||||
|
logo_html = build_logo_html(shop_name)
|
||||||
footer =
|
footer =
|
||||||
if unsubscribe_url do
|
if unsubscribe_url do
|
||||||
"""
|
"""
|
||||||
@ -167,7 +168,7 @@ defmodule Berrypod.Newsletter.Notifier do
|
|||||||
<table role="presentation" class="email-container" width="560" cellpadding="0" cellspacing="0" style="max-width: 560px; width: 100%; background-color: #ffffff; border-radius: 8px;">
|
<table role="presentation" class="email-container" width="560" cellpadding="0" cellspacing="0" style="max-width: 560px; width: 100%; background-color: #ffffff; border-radius: 8px;">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="email-header" style="padding: 24px 32px 16px; border-bottom: 1px solid #e5e7eb;">
|
<td class="email-header" style="padding: 24px 32px 16px; border-bottom: 1px solid #e5e7eb;">
|
||||||
<strong style="font-size: 18px; color: #111827;">#{esc(shop_name)}</strong>
|
#{logo_html}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@ -186,6 +187,45 @@ defmodule Berrypod.Newsletter.Notifier do
|
|||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Builds the header logo/name HTML. Uses the shop logo if configured,
|
||||||
|
# falls back to the favicon (served as PNG), or plain text.
|
||||||
|
defp build_logo_html(shop_name) do
|
||||||
|
base_url = BerrypodWeb.Endpoint.url()
|
||||||
|
theme = Berrypod.Settings.get_theme_settings()
|
||||||
|
|
||||||
|
cond do
|
||||||
|
# Logo image configured and not SVG (email clients don't support SVG)
|
||||||
|
theme.logo_image_id && !is_svg_image?(theme.logo_image_id) ->
|
||||||
|
src = "#{base_url}/image_cache/#{theme.logo_image_id}.webp"
|
||||||
|
height = theme.logo_size || 36
|
||||||
|
|
||||||
|
~s(<img src="#{esc(src)}" alt="#{esc(shop_name)}" height="#{height}" style="height: #{height}px; width: auto; display: block;">)
|
||||||
|
|
||||||
|
# Favicon icon exists (served as PNG at /apple-touch-icon.png)
|
||||||
|
has_favicon_icon?() ->
|
||||||
|
src = "#{base_url}/apple-touch-icon.png"
|
||||||
|
|
||||||
|
~s(<img src="#{esc(src)}" alt="#{esc(shop_name)}" width="36" height="36" style="height: 36px; width: 36px; display: inline-block; vertical-align: middle; border-radius: 4px; margin-right: 8px;">) <>
|
||||||
|
~s(<strong style="font-size: 18px; color: #111827; vertical-align: middle;">#{esc(shop_name)}</strong>)
|
||||||
|
|
||||||
|
# No image — text only
|
||||||
|
true ->
|
||||||
|
~s(<strong style="font-size: 18px; color: #111827;">#{esc(shop_name)}</strong>)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp is_svg_image?(image_id) do
|
||||||
|
case Berrypod.Repo.get(Berrypod.Media.Image, image_id) do
|
||||||
|
%{is_svg: true} -> true
|
||||||
|
_ -> false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp has_favicon_icon? do
|
||||||
|
require Ecto.Query
|
||||||
|
Berrypod.Repo.exists?(Ecto.Query.from(i in Berrypod.Media.Image, where: i.image_type == "icon"))
|
||||||
|
end
|
||||||
|
|
||||||
# Turns bare URLs in escaped text into clickable links.
|
# Turns bare URLs in escaped text into clickable links.
|
||||||
defp linkify(escaped_text) do
|
defp linkify(escaped_text) do
|
||||||
Regex.replace(~r/(https?:\/\/[^\s<]+)/, escaped_text, fn url, _ ->
|
Regex.replace(~r/(https?:\/\/[^\s<]+)/, escaped_text, fn url, _ ->
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user