Skip to content

Commit d225ff7

Browse files
committed
Take into account parent templates when rendering mail content. Fixes #10
1 parent bcadd81 commit d225ff7

File tree

5 files changed

+41
-6
lines changed

5 files changed

+41
-6
lines changed

templated_mail/mail.py

+18-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from django.core import mail
44
from django.template.context import make_context
55
from django.template.loader import get_template
6+
from django.template.loader_tags import BlockNode, ExtendsNode
67
from django.views.generic.base import ContextMixin
78

89

@@ -60,8 +61,9 @@ def render(self):
6061
context = make_context(self.get_context_data(), request=self.request)
6162
template = get_template(self.template_name)
6263
with context.bind_template(template.template):
63-
for node in template.template.nodelist:
64-
self._process_node(node, context)
64+
blocks = self._get_blocks(template.template.nodelist, context)
65+
for block_node in blocks.values():
66+
self._process_block(block_node, context)
6567
self._attach_body()
6668

6769
def send(self, to, *args, **kwargs):
@@ -77,10 +79,21 @@ def send(self, to, *args, **kwargs):
7779

7880
super(BaseEmailMessage, self).send(*args, **kwargs)
7981

80-
def _process_node(self, node, context):
81-
attr = self._node_map.get(getattr(node, 'name', ''))
82+
def _process_block(self, block_node, context):
83+
attr = self._node_map.get(block_node.name)
8284
if attr is not None:
83-
setattr(self, attr, node.render(context).strip())
85+
setattr(self, attr, block_node.render(context).strip())
86+
87+
def _get_blocks(self, nodelist, context):
88+
blocks = {}
89+
for node in nodelist:
90+
if isinstance(node, ExtendsNode):
91+
parent = node.get_parent(context)
92+
blocks.update(self._get_blocks(parent.nodelist, context))
93+
blocks.update({
94+
node.name: node for node in nodelist.get_nodes_by_type(BlockNode)
95+
})
96+
return blocks
8497

8598
def _attach_body(self):
8699
if self.body and self.html:

tests/templates/extends.html

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{% extends "text_and_html_mail.html" %}
2+
3+
{% block html_body %}Some extended HTML body{% endblock html_body %}

tests/templates/html_mail.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{% block subject %}HTML mail subject{% endblock %}
22

3-
{% block html_body %}<p>Foobar email content</p>{% endblock %}
3+
{% block html_body %}<p>Foobar email content</p>{% endblock %}

tests/templates/nested_extends.html

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{% extends "extends.html" %}
2+
3+
{% block text_body %}Some extended text body{% endblock text_body %}

tests/test_mail.py

+16
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,19 @@ def test_extending_mail_with_context_mixin(self):
225225

226226
self.assertEquals(context['foo'], 'bar')
227227
self.assertEquals(context['thing'], 42)
228+
229+
def test_extending_mail_template(self):
230+
email_message = BaseEmailMessage(template_name='extends.html')
231+
email_message.render()
232+
233+
self.assertEquals(email_message.subject, 'Text and HTML mail subject')
234+
self.assertEquals(email_message.body, 'Foobar email content')
235+
self.assertEquals(email_message.html, 'Some extended HTML body')
236+
237+
def text_nested_extending_mail_template(self):
238+
email_message = BaseEmailMessage(template_name='nested_extends.html')
239+
email_message.render()
240+
241+
self.assertEquals(email_message.subject, 'Text and HTML mail subject')
242+
self.assertEquals(email_message.body, 'Some extended text body')
243+
self.assertEquals(email_message.html, 'Some extended HTML body')

0 commit comments

Comments
 (0)