Created
July 19, 2020 01:28
-
-
Save darthwade/097ddadf47d50d683846fbec5400e5ad to your computer and use it in GitHub Desktop.
Django email templates where subject and text/html body are in the same file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.conf import settings | |
from django.core import mail | |
from django.template.context import make_context | |
from django.template.loader import get_template | |
from django.template.loader_tags import BlockNode, ExtendsNode | |
class BaseEmailMessage(mail.EmailMultiAlternatives): | |
template_name = None | |
context = {} | |
html = None | |
_node_map = { | |
"subject": "subject", | |
"text": "body", | |
"html": "html", | |
# TODO: support extends "email/base.html" | |
# "text_body": "body", | |
# "html_body": "html", | |
} | |
def __init__(self, template_name=None, context=None, *args, **kwargs): | |
super(BaseEmailMessage, self).__init__(*args, **kwargs) | |
if template_name is not None: | |
self.template_name = template_name | |
if context is not None: | |
self.context = context | |
def get_template_name(self): | |
return self.template_name | |
def get_context_data(self): | |
return self.context | |
def send(self, *args, **kwargs): | |
self.render() | |
super(BaseEmailMessage, self).send(*args, **kwargs) | |
def render(self): | |
template = get_template(self.get_template_name()) | |
context = make_context(self.get_context_data()) | |
with context.bind_template(template.template): | |
blocks = self._get_blocks(template.template.nodelist, context) | |
for block_node in blocks.values(): | |
self._process_block(block_node, context) | |
self._attach_body() | |
def _process_block(self, block_node, context): | |
attr = self._node_map.get(block_node.name) | |
if attr is not None: | |
setattr(self, attr, block_node.render(context).strip()) | |
def _get_blocks(self, nodelist, context): | |
blocks = {} | |
for node in nodelist: | |
if isinstance(node, ExtendsNode): | |
parent = node.get_parent(context) | |
blocks.update(self._get_blocks(parent.nodelist, context)) | |
blocks.update( | |
{node.name: node for node in nodelist.get_nodes_by_type(BlockNode)} | |
) | |
return blocks | |
def _attach_body(self): | |
if self.body and self.html: # when both text_body and html_body provided | |
self.attach_alternative(self.html, "text/html") | |
elif self.html: # when only html_body provided | |
self.body = self.html | |
self.content_subtype = "html" | |
def send_email( | |
template_name, | |
to, | |
context=None, | |
attachments=None, | |
cc=settings.EMAIL_DEFAULT_CC, | |
bcc=settings.EMAIL_DEFAULT_BCC, | |
reply_to=settings.EMAIL_DEFAULT_REPLY_TO, | |
from_email=settings.DEFAULT_FROM_EMAIL, | |
headers=settings.EMAIL_DEFAULT_HEADERS, | |
fail_silently=settings.EMAIL_DEFAULT_FAIL_SILENTLY, | |
): | |
return BaseEmailMessage( | |
template_name=template_name, | |
to=to, | |
context={**settings.EMAIL_DEFAULT_TEMPLATE_CONTEXT, **context}, | |
attachments=attachments, | |
cc=cc, | |
bcc=bcc, | |
reply_to=reply_to, | |
from_email=from_email, | |
headers=headers, | |
).send(fail_silently=fail_silently) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% block subject %}[Action Required] ⚠️ {{user.first_name}}, review your information{% endblock %} | |
{% block text %} | |
Hi {{user.first_name}}, | |
{% endblock %} | |
{% block html %} | |
<p>Hi {{user.first_name}},</p> | |
{% endblock %} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment