- Implemented email settings configuration in the admin panel, allowing for SMTP settings and notification preferences. - Created a new template for email settings with fields for SMTP host, port, username, password, sender address, and recipients. - Added JavaScript functionality to handle loading, saving, and validating email settings. - Introduced email templates management, enabling the listing, editing, and saving of email templates. - Updated navigation to include links to email settings and templates. - Added tests for email settings and templates to ensure proper functionality and validation.
87 lines
2.7 KiB
Python
87 lines
2.7 KiB
Python
"""Email template management helpers."""
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from typing import Dict, List
|
|
|
|
from ..database import get_app_settings, update_app_setting
|
|
from .. import settings
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class EmailTemplateDefinition:
|
|
"""Definition metadata describing an editable email template."""
|
|
|
|
id: str
|
|
setting_key: str
|
|
name: str
|
|
description: str
|
|
default_content: str
|
|
|
|
|
|
EMAIL_TEMPLATE_DEFINITIONS: Dict[str, EmailTemplateDefinition] = {
|
|
"newsletter_confirmation": EmailTemplateDefinition(
|
|
id="newsletter_confirmation",
|
|
setting_key="newsletter_confirmation_template",
|
|
name="Newsletter Confirmation",
|
|
description="HTML email sent to subscribers immediately after they confirm their newsletter signup.",
|
|
default_content=getattr(
|
|
settings, "NEWSLETTER_CONFIRMATION_TEMPLATE", "").strip(),
|
|
),
|
|
}
|
|
|
|
|
|
def list_templates() -> List[dict]:
|
|
"""Return a list of metadata describing available email templates."""
|
|
return [
|
|
{
|
|
"id": definition.id,
|
|
"name": definition.name,
|
|
"description": definition.description,
|
|
}
|
|
for definition in EMAIL_TEMPLATE_DEFINITIONS.values()
|
|
]
|
|
|
|
|
|
def _load_stored_templates() -> dict:
|
|
"""Return stored template values keyed by their setting key."""
|
|
return get_app_settings()
|
|
|
|
|
|
def load_template(template_id: str) -> dict:
|
|
"""Return template metadata and content for the requested template."""
|
|
if template_id not in EMAIL_TEMPLATE_DEFINITIONS:
|
|
raise KeyError(template_id)
|
|
|
|
definition = EMAIL_TEMPLATE_DEFINITIONS[template_id]
|
|
stored = _load_stored_templates()
|
|
content = stored.get(definition.setting_key, definition.default_content)
|
|
|
|
return {
|
|
"id": definition.id,
|
|
"name": definition.name,
|
|
"description": definition.description,
|
|
"content": content,
|
|
}
|
|
|
|
|
|
def persist_template(template_id: str, content: str) -> dict:
|
|
"""Persist template content and return the updated template payload."""
|
|
if template_id not in EMAIL_TEMPLATE_DEFINITIONS:
|
|
raise KeyError(template_id)
|
|
|
|
definition = EMAIL_TEMPLATE_DEFINITIONS[template_id]
|
|
content = (content or "").strip()
|
|
update_app_setting(definition.setting_key, content)
|
|
return load_template(template_id)
|
|
|
|
|
|
def get_template_content(template_id: str) -> str:
|
|
"""Return just the template body, falling back to defaults when unset."""
|
|
if template_id not in EMAIL_TEMPLATE_DEFINITIONS:
|
|
raise KeyError(template_id)
|
|
|
|
definition = EMAIL_TEMPLATE_DEFINITIONS[template_id]
|
|
stored = _load_stored_templates()
|
|
return stored.get(definition.setting_key, definition.default_content)
|