From fls
Create or modify branded HTML+text multipart emails for django-allauth flows. Use when working with email templates, email styling, or notification emails.
npx claudepluginhub preludetech/django-craftThis skill is limited to using the following tools:
FLS provides professional branded HTML+text multipart emails for all django-allauth email flows. Emails use table-based layouts with CSS inlining for maximum email client compatibility. Brand colors are automatically pulled from the Tailwind CSS configuration.
Builds responsive HTML email templates using React components with Tailwind support, previews in dev server, renders to HTML, and sends via Resend for transactional emails like welcomes and notifications.
Builds HTML email templates using React components with Tailwind, renders to HTML, previews via dev server, adds visual editor, and sends via Resend for transactional emails like welcomes and notifications.
Build responsive email templates with MJML in .NET apps using Mjml.Net. Compiles to cross-client HTML for Outlook, Gmail, Apple Mail with rendering and variables.
Share bugs, ideas, or general feedback.
FLS provides professional branded HTML+text multipart emails for all django-allauth email flows. Emails use table-based layouts with CSS inlining for maximum email client compatibility. Brand colors are automatically pulled from the Tailwind CSS configuration.
All email templates extend one of two base templates:
| Template | Purpose |
|---|---|
emails/base_email.html | HTML base with {% premailer %} CSS inlining, table-based layout, header, greeting, content, CTA, sign-off, footer |
emails/base_email.txt | Plain text base with greeting, content, sign-off, site info |
emails/base_notification_email.html | Extends base_email.html, adds a security info section (IP, browser, timestamp) |
emails/base_notification_email.txt | Extends base_email.txt, adds plain text security info |
base_email.html provides:
{% block subject %} -- Email subject line (used in <title>){% block content %} -- Main email body{% block cta %} -- Call-to-action button area (below content)base_notification_email.html adds:
{% block notification_content %} -- Use this instead of content when extending the notification base{% block security_info %} -- Security details block (IP, browser, timestamp); pre-filled, override to customizeThese files are included by the base templates. Downstream projects override them by placing a file at the same template path.
| Include | Format | Purpose |
|---|---|---|
emails/includes/greeting.html | HTML | Opening greeting (e.g., "Hi {{ user.first_name }}") |
emails/includes/greeting.txt | Text | Plain text opening greeting |
emails/includes/sign_off.html | HTML | Closing sign-off |
emails/includes/sign_off.txt | Text | Plain text closing sign-off |
emails/includes/header.html | HTML | Email header with optional logo or site name |
emails/includes/footer_links.html | HTML | Footer links section (empty by default) |
To override, create a file at the same path in your project's templates directory (which must appear before FLS in TEMPLATES dirs or INSTALLED_APPS).
| Variable | Source | Description |
|---|---|---|
email_color_primary | settings.EMAIL_COLOR_PRIMARY | Header background, button background, link color |
email_color_foreground | settings.EMAIL_COLOR_FOREGROUND | Body text color |
email_color_muted | settings.EMAIL_COLOR_MUTED | Footer text, secondary text, security info |
email_font_family | settings.EMAIL_FONT_FAMILY | Font stack for the email body |
email_logo_static_path | settings.EMAIL_LOGO_STATIC_PATH | Optional path to logo in static files |
current_site | Django Sites framework | Site name and domain for footer |
user | AccountAdapter.send_notification_mail() | User object, injected for notification emails |
Context variables are injected by the email_settings context processor in freedom_ls/accounts/context_processors.py.
All templates are in freedom_ls/accounts/templates/account/email/.
| Email Type | Template Prefix | Base Template | Key Context Variables |
|---|---|---|---|
| Email confirmation | email_confirmation | base_email | activate_url |
| Email confirmation (signup) | email_confirmation_signup | Includes email_confirmation | activate_url |
| Password reset | password_reset_key | base_email | password_reset_url |
| Unknown account | unknown_account | base_email | signup_url |
| Login code | login_code | base_email | code |
| Account already exists | account_already_exists | base_email | password_reset_url |
| Password changed | password_changed | base_notification_email | user, ip, user_agent, timestamp |
| Password set | password_set | base_notification_email | user, ip, user_agent, timestamp |
| Email changed | email_changed | base_notification_email | user, from_email, to_email |
| Email confirmed | email_confirm | base_notification_email | user |
| Email deleted | email_deleted | base_notification_email | user, deleted_email |
Each type has three files: *_subject.txt, *_message.html, *_message.txt.
Settings are defined in config/settings_base.py.
| Setting | Default | Description |
|---|---|---|
EMAIL_LOGO_STATIC_PATH | None | Path to logo image in static files (e.g., "images/logo.png") |
EMAIL_COLOR_PRIMARY | Parsed from Tailwind (--color-primary) or #2B6CB0 | Header background, button color |
EMAIL_COLOR_FOREGROUND | Parsed from Tailwind (--color-foreground) or #1A2332 | Body text color |
EMAIL_COLOR_MUTED | Parsed from Tailwind (--color-muted) or #4A5568 | Footer and secondary text color |
EMAIL_FONT_FAMILY | "Arial, Helvetica, sans-serif" | Font stack |
ACCOUNT_EMAIL_NOTIFICATIONS | True | Enable allauth notification emails (password changed, etc.) |
The base_email.html template wraps its entire content in {% premailer %}...{% endpremailer %} (from django-premailer). This converts the <style> block into inline style attributes on each HTML element at render time. Since this is in the base template, all child templates get CSS inlining automatically.
The color parser in freedom_ls/accounts/email_utils.py reads --color-* custom properties from tailwind.components.css at Django startup:
_tw_colors = parse_tailwind_colors(str(BASE_DIR / "tailwind.components.css"))
EMAIL_COLOR_PRIMARY = _tw_colors.get("primary", "#2B6CB0")
Changing --color-primary, --color-foreground, or --color-muted in tailwind.components.css automatically updates email colors on the next server restart.
Dev settings (config/settings_dev.py) use the file-based email backend:
EMAIL_BACKEND = "django.core.mail.backends.filebased.EmailBackend"
EMAIL_FILE_PATH = "gitignore/emails"
Trigger any email flow (signup, password reset, etc.) and check the generated files in gitignore/emails/.
Extend the base template and use the content and cta blocks:
{% extends "emails/base_email.html" %}
{% block content %}
<p style="margin: 0 0 16px 0; font-size: 16px; line-height: 1.5;">Your custom email content here.</p>
{% endblock %}
{% block cta %}
<table role="presentation" cellpadding="0" cellspacing="0" style="margin: 24px 0;">
<tr>
<td style="background-color: {{ email_color_primary }}; border-radius: 6px;">
<a href="{{ action_url }}" style="display: inline-block; padding: 12px 32px; color: #FFFFFF; text-decoration: none; font-weight: bold; font-size: 16px;">Take Action</a>
</td>
</tr>
</table>
{% endblock %}
For notification-style emails (with security info), extend emails/base_notification_email.html and use {% block notification_content %} instead.