Skip to content

💄(mail) adopt the new LaSuite email layout - #947

Open
NathanVss wants to merge 20 commits into
mainfrom
feat/email-lasuite-template
Open

NathanVss wants to merge 20 commits into
mainfrom
feat/email-lasuite-template

Conversation

@NathanVss

@NathanVss NathanVss commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Closes #926

Emails now follow the new LaSuite layout: logo, title banner, message, button, pitch, signature, product icons and a footer with the government and suite logos and links.

Changes

  • Email sending is centralized in core/services/mail.py, which builds the branding context shared by all templates.
  • Branding comes from settings, so instances not operated by DINUM can use their own. Each optional block (government logo, suite logo, product icons, newsletter, support, terms of use) is hidden when its setting is unset. Support and terms of use default to FRONTEND_HELP_MENU_CONFIG.
  • The frontend serves the email images and the Marianne font, with a CORS header on fonts for webmails. Arial is the fallback, forced on Outlook.
  • Invitation emails show the sender and the item in bold.
  • Fixes: subjects no longer lowercase names and titles, plain text emails no longer show ".

Deployment

Instances need to set DJANGO_EMAIL_APP_NAME to keep a name other than Drive, and can set the new DJANGO_EMAIL_* settings once the frontend is deployed. See UPGRADE.md.

Before

Capture d’écran 2026-10-30 à 15 59 53

After

Capture d’écran 2026-10-30 à 15 59 41

The user, user reconciliation import and item models each had their own
copy of the code rendering and sending emails. Moving it to a mail
service gives one place to build the branding context shared by all
templates, before the new LaSuite layout adds more of it.
The subject was capitalized with str.capitalize, which also lowercases
the rest of the string: "Alice Martin shared an item with you: Q3
Report" became "Alice martin shared an item with you: q3 report".
Only the first letter is now uppercased.
Plain text templates were rendered with autoescaping like the HTML
ones, so quotes in messages showed up as " and ampersands as
&. The generated text templates now turn autoescaping off, since
plain text is never interpreted as HTML.
The cached mail templates were keyed on the mjml sources, the build
scripts and the lockfile only. A change to html-to-text.config.json
alone reused stale plain text templates in the backend tests.
The new LaSuite email layout shows a font, logos, product icons and
footer links that differ between instances. They come from settings
so that an instance not operated by DINUM can use its own branding,
and each optional block can be hidden by leaving its setting unset.

The support and terms of use links default to the ones of the frontend
help menu, which instances already configure.
The new LaSuite email layout needs logos, product icons and the
Marianne font hosted at stable public URLs, which the frontend assets
provide. Images are stored at twice their displayed size to stay sharp
on high density screens.

Webmails load fonts from another origin, so the fonts are served with
a CORS header, by nginx in production and by Next in development.
The new LaSuite layout shows a short banner title, then a sentence
with the sender and the item in bold. The sentence is built as HTML
with format_html, so the sender name and the item title stay escaped.
The plain text version strips the tags of such values instead of
showing them.

The role is shown with its label, as in the rest of the application,
and the item title is part of the sentence instead of a separate link.
Give Drive emails the same look as the other LaSuite products: logo,
title banner, message, button, pitch, signature, product icons and a
footer with the government and suite logos and links. Shared parts
live in partials so the invitation and reconciliation emails only
define their message and button.

The Marianne font is loaded where email clients support web fonts,
with Arial as fallback, forced for Outlook which otherwise shows Times
New Roman. Dark mode is disabled where clients allow it because the
colors are not designed for it. Images are left out of the plain text
version where they only added their URL.

Django tags inside the CSS are wrapped in comments, otherwise mjml
reformats them and breaks the template.
User.send_email and UserReconciliationCsvImport.send_email looked like
generic helpers but always render the reconciliation template. Naming
them send_reconciliation_email makes this clear at call sites and
avoids using them for other emails by mistake.
French emails used to name the product through the translations and
now use DJANGO_EMAIL_APP_NAME, which defaults to Drive: instances must
set it to keep their name. The new branding settings and the assets
served by the frontend also need to be configured in the right order.
…hanges

👷(ci) share the mail templates cache key between workflows

The backend and e2e tests restored the built mail templates with a key
hashing the mjml sources only, while the build job saved them under a
key also hashing the build scripts and lockfile. The keys never
matched: tests kept using a cache saved in May, and a pull request
changing the mjml sources found no template at all.

The build job now exposes its key, which also covers the text
conversion config, and the tests fail early when templates are missing.
@NathanVss
NathanVss requested a review from kernicPanel October 30, 2026 16:21

@kernicPanel kernicPanel left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • New strings have an empty msgstr in de_DE and nl_NL and their previous translations are removed, so invitations from senders using these languages have an English body under a translated subject.
  • "Drive" stays hardcoded in the reconciliation emails (core/models.py:633 and :716) while the rest of the text uses DJANGO_EMAIL_APP_NAME, so an instance named Fichiers sends "on Drive" above "The Fichiers team".

Comment thread UPGRADE.md Resolved
Comment thread src/backend/core/services/mail.py Resolved
Comment thread src/mail/mjml/partial/footer.mjml Resolved
…mplate

# Conflicts:
#	src/backend/core/models.py
#	src/backend/core/tests/test_models_users.py
@sonarqubecloud

sonarqubecloud Bot commented Nov 3, 2026

Copy link
Copy Markdown

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update the email template to the new LaSuite design

2 participants