feature: mail templates (registry, DB-backed content, sandboxed Jinja2, API) #6
No reviewers
Labels
No labels
breaking
bug
ci
dependencies
documentation
feature
security
skip-changelog
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Gilles/poulpinou-django!6
Loading…
Reference in a new issue
No description provided.
Delete branch "feature/mail-templates"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #5.
Summary
poulpinou.registry: static declaration of mail types (key, label, variables, default subject/body) by host apps, plus global variables merged into every render.MailTemplate/MailTemplateImage/MailTemplateAttachment: the actual, DB-editable content per key, seeded from the registry on first access.poulpinou.rendering: sandboxed Jinja2 (ImmutableSandboxedEnvironment, noLoader, soft-undefined so an unknown/removed variable renders blank, including inside{% for %}) -- supports{% if %}/{% for %}, same{{ var }}syntax as drh's current templates for a later read-based migration. HTML body autoescaped, subject not.poulpinou.sending.send_mail_type(key, recipient, context): renders + attaches + sends.[api]extra (djangorestframework): list/detail/patch/reset + image/attachment upload endpoints, permission classes configurable viaPOULPINOU_MAIL_TEMPLATE_PERMISSION_CLASSES.Migrating drh itself onto this is a separate, later PR in ws-backend -- out of scope here.
Test plan
tox -e py313(pytest, 37 tests: registry, rendering incl. sandbox/autoescape/if-for, models, sending, API)tox -e lint(pylint 10/10)tox -e bandit(no issues)tox -e format-check🤖 Generated with Claude Code
https://claude.ai/code/session_013EeueXTWCT4Y6EbeideZcm
Generalizes the EmailTemplate pattern hardcoded in drh's apps.events into a reusable poulpinou feature: - poulpinou.registry: static, code-side declaration of mail types (key, label, variables, default subject/body), registered by host apps; plus global variables merged into every render. - MailTemplate/MailTemplateImage/MailTemplateAttachment: the actual, DB-editable subject/body/attachments per key, seeded from the registry on first access. - poulpinou.rendering: sandboxed Jinja2 (ImmutableSandboxedEnvironment, no Loader, soft-undefined so an unknown/removed variable renders blank instead of raising) -- supports {% if %}/{% for %}, same {{ var }} syntax as drh's current templates so a later read-based migration doesn't need template rewrites. HTML body is autoescaped, subject is not. - poulpinou.sending.send_mail_type(key, recipient, context): renders, attaches, sends. - Optional [api] extra (djangorestframework): list/detail/patch/reset endpoints + image/attachment upload, permission classes configurable via POULPINOU_MAIL_TEMPLATE_PERMISSION_CLASSES. Closes #5 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013EeueXTWCT4Y6EbeideZcm📊 Rapports Argus pour cette PR