From 7b59b0c43aa770ced434816868a8363a0c40e74b Mon Sep 17 00:00:00 2001 From: jacklinke Date: Tue, 22 Oct 2024 21:35:50 -0400 Subject: [PATCH] Implement configurable default values for the subject and preheader --- docs/usage.md | 17 ++++ .../test_no_subject_preheader.md | 6 ++ .../test_subject_preheader_provided.md | 9 +++ .../test_django_templated_email_md.py | 79 ++++++++++++++++++- src/templated_email_md/backend.py | 10 ++- 5 files changed, 116 insertions(+), 5 deletions(-) create mode 100644 example_project/example/templates/templated_email/test_no_subject_preheader.md create mode 100644 example_project/example/templates/templated_email/test_subject_preheader_provided.md diff --git a/docs/usage.md b/docs/usage.md index 2080271..7e26131 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -354,6 +354,23 @@ with translation.override(language_code): ## Edge Cases and Considerations +### Default Subject and Preheader + +- **Providing Defaults**: If the `subject` and `preheader` blocks are not defined in the template, the default values are used. +- **Customizing Defaults**: You can set default values for the subject and preheader in the context when sending the email. + +#### Settings + +You can also set default values for the subject and preheader in your Django settings. These are used if a value is not provided +in the template or context, or if you have set `fail_silently` to `True` and an error occurs. + +```python +TEMPLATED_EMAIL_DEFAULT_SUBJECT = 'Default Subject' +TEMPLATED_EMAIL_DEFAULT_PREHEADER = 'Default Preheader' +``` + +If not set, the default value for subject is `'Hello!'` and for preheader is `''`. + ### Subject Overriding - **From Context**: You can override the subject by providing a `subject` key in the context. diff --git a/example_project/example/templates/templated_email/test_no_subject_preheader.md b/example_project/example/templates/templated_email/test_no_subject_preheader.md new file mode 100644 index 0000000..8c74064 --- /dev/null +++ b/example_project/example/templates/templated_email/test_no_subject_preheader.md @@ -0,0 +1,6 @@ +{% block content %} + +# Hello {{ name }}! + +This is a test message. +{% endblock %} diff --git a/example_project/example/templates/templated_email/test_subject_preheader_provided.md b/example_project/example/templates/templated_email/test_subject_preheader_provided.md new file mode 100644 index 0000000..b54a3a0 --- /dev/null +++ b/example_project/example/templates/templated_email/test_subject_preheader_provided.md @@ -0,0 +1,9 @@ +{% block subject %}Subject from Template{% endblock %} +{% block preheader %}Preheader from Template{% endblock %} + +{% block content %} + +# Hello {{ name }}! + +This is a test message. +{% endblock %} diff --git a/example_project/test_django_templated_email_md.py b/example_project/test_django_templated_email_md.py index 4434b70..adc2a20 100644 --- a/example_project/test_django_templated_email_md.py +++ b/example_project/test_django_templated_email_md.py @@ -5,6 +5,7 @@ from django.core import mail from django.template import TemplateDoesNotExist from django.utils import translation +from django.utils.translation import gettext as _ from templated_email import send_templated_mail from templated_email_md.backend import MarkdownTemplateBackend @@ -137,7 +138,7 @@ def test_fail_silently(): # Should get a fallback response instead of an exception assert "Email template rendering failed" in response["html"] assert "Email template rendering failed" in response["plain"] - assert response["subject"] == "No Subject" + assert response["subject"] == "Hello!" def test_subject_from_context(backend): @@ -379,3 +380,79 @@ def test_remove_comments(): assert "HTML Comment" not in cleaned_html assert "CSS Comment" not in cleaned_html assert "JavaScript Comment" not in cleaned_html + + +def test_default_subject_and_preheader(): + """ + Test that the default subject and preheader are used when + not provided in the template or context. + """ + # Send an email without subject or preheader in template or context + send_templated_mail( + template_name="test_no_subject_preheader", + from_email="from@example.com", + recipient_list=["to@example.com"], + context={"name": "Test User"}, + ) + + assert len(mail.outbox) == 1 + email = mail.outbox[0] + + # Default subject should be 'Hello!' as per the default in the backend + assert email.subject == _("Hello!") + # Preheader should be empty string by default + # Since preheader may not be directly visible, check in the HTML content + html_content = email.alternatives[0][0] + assert "Hello!" in email.subject + assert '" in html_content + + +def test_custom_default_subject_and_preheader(): + """ + Test that the custom default subject and preheader from settings + are used when not provided in the template or context. + """ + settings.TEMPLATED_EMAIL_DEFAULT_SUBJECT = "Default Subject from Settings" + settings.TEMPLATED_EMAIL_DEFAULT_PREHEADER = "Default Preheader from Settings" + # Send an email without subject or preheader in template or context + send_templated_mail( + template_name="test_no_subject_preheader", + from_email="from@example.com", + recipient_list=["to@example.com"], + context={"name": "Test User"}, + ) + + assert len(mail.outbox) == 1 + email = mail.outbox[0] + + # Subject should be the custom default from settings + assert email.subject == "Default Subject from Settings" + # Preheader should be the custom default from settings + html_content = email.alternatives[0][0] + assert 'Default Preheader from Settings" in html_content + + +def test_subject_and_preheader_provided(): + """ + Test that when subject and preheader are provided in the template, + they override the default values. + """ + # Send an email with subject and preheader in the template + send_templated_mail( + template_name="test_subject_preheader_provided", + from_email="from@example.com", + recipient_list=["to@example.com"], + context={"name": "Test User"}, + ) + + assert len(mail.outbox) == 1 + email = mail.outbox[0] + + # Subject and preheader should be as provided in the template + assert email.subject == "Subject from Template" + html_content = email.alternatives[0][0] + assert 'Preheader from Template" in html_content diff --git a/src/templated_email_md/backend.py b/src/templated_email_md/backend.py index c98073e..aa2abb5 100644 --- a/src/templated_email_md/backend.py +++ b/src/templated_email_md/backend.py @@ -73,6 +73,8 @@ def __init__( ], ) self.html2text_settings = getattr(settings, "TEMPLATED_EMAIL_HTML2TEXT_SETTINGS", {}) + self.default_subject = getattr(settings, "TEMPLATED_EMAIL_DEFAULT_SUBJECT", _("Hello!")) + self.default_preheader = getattr(settings, "TEMPLATED_EMAIL_DEFAULT_PREHEADER", _("")) def _render_markdown(self, content: str) -> str: """Convert Markdown content to HTML. @@ -241,8 +243,8 @@ def _render_email( return { "html": fallback_content, "plain": fallback_content, - "subject": _("No Subject"), - "preheader": _("No Preheader"), + "subject": self.default_subject, + "preheader": self.default_preheader, } raise @@ -259,7 +261,7 @@ def _get_subject_from_template(self, template_path: str, context: Dict[str, Any] try: subject = render_block_to_string(template_path, "subject", context).strip() except BlockNotFound: - subject = _("No Subject") + subject = self.default_subject # Override subject if 'subject' is in context subject = context.get("subject", subject) @@ -279,7 +281,7 @@ def _get_preheader_from_template(self, template_path: str, context: Dict[str, An try: preheader = render_block_to_string(template_path, "preheader", context).strip() except BlockNotFound: - preheader = _("No Preheader") + preheader = self.default_preheader # Override preheader if 'preheader' is in context preheader = context.get("preheader", preheader)