[Django] #17193: Send templated email.

31 views
Skip to first unread message

Django

unread,
Nov 10, 2011, 1:11:37 PM11/10/11
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+--------------------
Reporter: tomchristie | Owner: nobody
Type: New feature | Status: new
Component: Core (Mail) | Version:
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 1
Easy pickings: 0 | UI/UX: 0
-----------------------------+--------------------
If your sending email it's likely that you want to render the body text
from template, but there's currently no shortcut to send an email based on
a template.

The attached patch is based on a stripped down version of
https://github.com/bradwhittington/django-templated-email

It adds `django.shortcuts.send_templated_mail`, which mirrors the existing
`send_mail`, but which renders the subject and body of the mail from a
template, rather than taking their values explicitly. It also supports
multipart html/plaintext emails.

The docs will look something like this...

**send_templated_mail(template_name, from_email, recipient_list,
dictionary=None, context_instance=None, fail_silently=False,
auth_user=None, auth_password=None, connection=None):**
Sends a mail, rendering the subject and body of the email from a
template.

The template should contain a block named 'subject', and either/both
of a 'plain' and/or 'html' block.

If only the 'plain' block exists, a plaintext email will be sent.

If only the 'html' block exists, the plaintext component will be
automatically generated from the html, and a multipart email will be sent.

If both the 'plain' and 'html' blocks exist, a multipart email will be
sent.

**Required arguments:**

`template_name` - The template that should be used to render the
email.

`from_email` - The sender's email address.

`recipient_list` - A list of reciepient's email addresses.

**Optional arguments:**

`dictionary` - The context dictionary used to render the template. By
default, this is an empty dictionary.

`context_instance` - The Context instance used to render the template.
By default, the template will be rendered with a Context instance (filled
with values from dictionary).

`fail_silently` - As in `send_mail`.

`auth_user` - As in `send_mail`.

`auth_password` - As in `send_mail`.

`connection` - As in `send_mail`.

--
Ticket URL: <https://code.djangoproject.com/ticket/17193>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Nov 10, 2011, 4:43:28 PM11/10/11
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+--------------------------------------
Reporter: tomchristie | Owner: nobody
Type: New feature | Status: new
Component: Core (Mail) | Version:
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+--------------------------------------
Changes (by tomchristie):

* needs_better_patch: => 0
* needs_tests: => 1
* needs_docs: => 1


--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:1>

Django

unread,
Nov 12, 2011, 7:15:59 AM11/12/11
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+------------------------------------
Reporter: tomchristie | Owner: nobody
Type: New feature | Status: new
Component: Core (Mail) | Version:
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+------------------------------------
Changes (by aaugustin):

* stage: Unreviewed => Accepted


Comment:

Yes, I think Django could provide this feature.

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:2>

Django

unread,
Nov 13, 2011, 10:08:22 PM11/13/11
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+------------------------------------
Reporter: tomchristie | Owner: nobody
Type: New feature | Status: new
Component: Core (Mail) | Version:
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+------------------------------------

Comment (by julianapplebaum):

I'm new to to the django dev community, and was hoping to write some unit
tests for this shortcut. Should I claim the ticket before doing that?
Sorry if this isn't the right place to be asking that.

- Julian Applebaum

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:3>

Django

unread,
Nov 14, 2011, 2:01:15 AM11/14/11
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+------------------------------------
Reporter: tomchristie | Owner: nobody
Type: New feature | Status: new
Component: Core (Mail) | Version:
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+------------------------------------

Comment (by aaugustin):

Yes, you should assign the ticket to yourself if you intend to work on it.

You'll find more information about our development process in the
[https://docs.djangoproject.com/en/dev/internals/contributing/
contributing guide].

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:4>

Django

unread,
Nov 15, 2011, 9:30:54 AM11/15/11
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+------------------------------------
Reporter: tomchristie | Owner: nobody
Type: New feature | Status: new
Component: Core (Mail) | Version:
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+------------------------------------
Changes (by tomchristie):

* needs_docs: 1 => 0


Comment:

Updated the patch to include documentation.

Also tweaked the API slightly - the email connection and message sending
has been decoupled from the message generation, and I've made some tweaks
to the arguments that `send_templated_mail` takes.

I think this should pretty much hit the sweet spot of making sure the
shortcut interface isn't overly complicated, whilst still providing for
the common case.

Julian - That'd be great. Feel free to get in touch with me off-list if
there's anything I can do to help with that - t...@tomchristie.com.

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:5>

Django

unread,
Nov 15, 2011, 9:48:22 AM11/15/11
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+------------------------------------
Reporter: tomchristie | Owner: nobody
Type: New feature | Status: new
Component: Core (Mail) | Version:
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+------------------------------------

Comment (by tomchristie):

Added some extra documentation in the existing email section, referring to
the shortcut.

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:6>

Django

unread,
Nov 15, 2011, 12:34:23 PM11/15/11
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+-------------------------------------------
Reporter: tomchristie | Owner: julianapplebaum
Type: New feature | Status: assigned
Component: Core (Mail) | Version:
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------
Changes (by julianapplebaum):

* status: new => assigned
* owner: nobody => julianapplebaum


Comment:

Replying to [comment:4 aaugustin]:

> Yes, you should assign the ticket to yourself if you intend to work on
it.
>
> You'll find more information about our development process in the
[https://docs.djangoproject.com/en/dev/internals/contributing/
contributing guide].

Thanks, and will do. Should have the patch up by Sunday night.

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:7>

Django

unread,
Nov 25, 2011, 12:10:38 AM11/25/11
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+-------------------------------------------
Reporter: tomchristie | Owner: julianapplebaum
Type: New feature | Status: assigned
Component: Core (Mail) | Version:
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------

Comment (by anonymous):

Quick status update:
It took me and the group I'm with longer than anticipated to get
everything up and running. We've written a few unit tests for
_render_mail, and aim to finish the rest this coming week. We apologize
for the delay.
Julian

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:8>

Django

unread,
Nov 28, 2011, 8:14:06 AM11/28/11
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+-------------------------------------------
Reporter: tomchristie | Owner: julianapplebaum
Type: New feature | Status: assigned
Component: Core (Mail) | Version:
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------

Comment (by tomchristie):

> We apologize for the delay.

Nothing to apologize for, it's a community effort - everything's
appreciated. :)

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:9>

Django

unread,
Nov 29, 2011, 11:46:47 AM11/29/11
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+-------------------------------------------
Reporter: tomchristie | Owner: julianapplebaum
Type: New feature | Status: assigned
Component: Core (Mail) | Version:
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------

Comment (by tevans.uk@…):

I have a few doubts about how this has been designed. With both html and
plain 'templates' actually just being blocks of a single template, it is
not possible to use template inheritance to design consistent emails,
which is a common use of the template system. Without this, styles would
need to be replicated across multiple templates.

In our send_mail wrapper at $JOB, we allow the user to pass in the stub
name of a template. The utility then attempts to render the templates
stub+'.html' and stub+'.txt', and uses the results of these to determine
whether we send a text/plain, text/html or multipart/alternative.

Instead of extracting the subject from a template, we allow it to be
passed in directly. We also add a language argument, which is used to
activate the appropriate translation prior to rendering the emails, or
coercing the subject to unicode. This allows us to send fully translated
emails appropriate for the user receiving the email - which may not be the
same as the language currently activated, if there is any, or the language
that has been activated for the current view.

Cheers

Tom (one of these days I'll remember my trac login)

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:10>

Django

unread,
Dec 14, 2011, 3:14:39 AM12/14/11
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+-------------------------------------------
Reporter: tomchristie | Owner: julianapplebaum
Type: New feature | Status: assigned
Component: Core (Mail) | Version:
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------

Comment (by tomchristie):

It's not quite true that you can't use template inheritance with this
style, although I've come around to thinking that it probably is a an
abuse of the 'block' tags to change their semantics for email templates.

I don't like the stub+'.txt', stub+'.html' for 2 reasons:

Firstly it's very easy for the two separate files to get out of sync, with
no easy way of noticing that's happened.
Secondly the stub + extension style isn't used anywhere else.

I think a better solution would be a single template and a flag to switch
between plaintext only, or html + autogenerated plaintext.

It's not impossible that I might get a spare couple of hours between now
and the 1.4 checkin deadline, but it's not looking all that likely, so may
have to defer this to 1.5.

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:11>

Django

unread,
Dec 27, 2011, 3:02:16 PM12/27/11
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+-------------------------------------------
Reporter: tomchristie | Owner: julianapplebaum
Type: New feature | Status: assigned
Component: Core (Mail) | Version:
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------

Comment (by julianapplebaum):

Hey Everyone

Just uploaded the diff file for my group's unit tests. Let me know if you
run into any issues with the tests/the diff file, etc.

Best,[[BR]]
Julian

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:12>

Django

unread,
Dec 28, 2011, 4:00:06 AM12/28/11
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+-------------------------------------------
Reporter: tomchristie | Owner: julianapplebaum
Type: New feature | Status: assigned
Component: Core (Mail) | Version:
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------

Comment (by anonymous):

Thanks Julian,

There may be some redesign needed of this feature, but either way those
tests look fairly comprehensive - should come in useful.

Tom

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:13>

Django

unread,
Dec 29, 2011, 10:04:10 AM12/29/11
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+-------------------------------------------
Reporter: tomchristie | Owner: julianapplebaum
Type: New feature | Status: assigned
Component: Core (Mail) | Version:
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------
Changes (by julianapplebaum):

* needs_tests: 1 => 0


--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:14>

Django

unread,
Jan 2, 2012, 3:39:46 PM1/2/12
to django-...@googlegroups.com
#17193: Send templated email.
-------------------------------------+-------------------------------------
Reporter: tomchristie | Owner:
Type: New feature | julianapplebaum
Component: Core (Mail) | Status: assigned
Severity: Normal | Version:
Keywords: | Resolution:
Has patch: 1 | Triage Stage: Design
Needs tests: 0 | decision needed
Easy pickings: 0 | Needs documentation: 0
| Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by julien):

* stage: Accepted => Design decision needed


Comment:

Thank you all for your great work on this patch. However, I'm struggling a
bit to see the value of adding this much new code for something that is
already quite easily achievable using `render_to_string()` and separate
templates.

I do agree that creating html+plain emails is still a little too hard in
Django, but in my opinion this could be simplified by introducing a new
helper class wrapping around `EmailMultiAlternatives` and providing a
simpler API and sensible defaults. For example, something like:
`HTMLEmailMessage(body_plain='...', body_html='...')`

In any case, I personally think that any template rendering should be left
to the user to do separately (for example by using `render_to_string()`).

For now I'm marking this ticket as DDN instead of wontfixing so that more
discussion can occur.

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:15>

Django

unread,
Jan 3, 2012, 6:47:49 AM1/3/12
to django-...@googlegroups.com
#17193: Send templated email.
-------------------------------------+-------------------------------------
Reporter: tomchristie | Owner:
Type: New feature | julianapplebaum
Component: Core (Mail) | Status: assigned
Severity: Normal | Version:
Keywords: | Resolution:
Has patch: 1 | Triage Stage: Design
Needs tests: 0 | decision needed
Easy pickings: 0 | Needs documentation: 0
| Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by anonymous):

Agreed that this isn't quite the right way to approach it.

I still think a `send_templated_email`, makes a lot of sense, but I've not
had time to revisit this yet and propose something simpler.

I'll take it to django-developers if and when that happens.
If anyone else takes this to the group first, please link to the
discussion from this ticket.

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:16>

Django

unread,
Mar 3, 2012, 1:01:44 AM3/3/12
to django-...@googlegroups.com
#17193: Send templated email.
-------------------------------------+-------------------------------------
Reporter: tomchristie | Owner:
Type: New feature | julianapplebaum
Component: Core (Mail) | Status: assigned
Severity: Normal | Version:
Keywords: | Resolution:
Has patch: 1 | Triage Stage: Design
Needs tests: 0 | decision needed
Easy pickings: 0 | Needs documentation: 0
| Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by streeter):

* cc: streeter (added)


--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:17>

Django

unread,
Mar 3, 2012, 4:44:43 AM3/3/12
to django-...@googlegroups.com
#17193: Send templated email.
-------------------------------------+-------------------------------------
Reporter: tomchristie | Owner:
Type: New feature | julianapplebaum
Component: Core (Mail) | Status: assigned
Severity: Normal | Version:
Keywords: | Resolution:
Has patch: 1 | Triage Stage: Design
Needs tests: 0 | decision needed
Easy pickings: 0 | Needs documentation: 0
| Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by artem.rizhov@…):

* cc: artem.rizhov@… (added)


Comment:

Hi there!

Replying to [comment:15 julien]:

> I do agree that creating html+plain emails is still a little too hard in
Django, but in my opinion this could be simplified by introducing a new
helper class wrapping around `EmailMultiAlternatives` and providing a
simpler API and sensible defaults. For example, something like:
`HTMLEmailMessage(body_plain='...', body_html='...')`

My implementation is based on `EmailMultiAlternatives` :) It's available
at !GitHub https://github.com/artemrizhov/django-mail-templated

Actuall, for me it
I've emailed to django-developers mailing list and proposed to merge it
into Django. However my proposition was declined.
http://groups.google.com/group/django-
developers/browse_frm/thread/4728f20dd8023dd9

I'd be glad to continue work on it, but there is no any reason to polish
it more for a while. :( At least unless I need some additional
functionality, or some activity is registered on the github project. :)
Propositions and suggestions are welcome.

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:18>

Django

unread,
Mar 3, 2012, 4:50:26 AM3/3/12
to django-...@googlegroups.com
#17193: Send templated email.
-------------------------------------+-------------------------------------
Reporter: tomchristie | Owner:
Type: New feature | julianapplebaum
Component: Core (Mail) | Status: assigned
Severity: Normal | Version:
Keywords: | Resolution:
Has patch: 1 | Triage Stage: Design
Needs tests: 0 | decision needed
Easy pickings: 0 | Needs documentation: 0
| Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by artem.rizhov@…):

Ooops..[[BR]]
{{{s/Actuall, for me it //}}}[[BR]]
Sorry for trash in the message.

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:19>

Django

unread,
Aug 30, 2012, 7:19:11 PM8/30/12
to django-...@googlegroups.com
#17193: Send templated email.
-------------------------------------+-------------------------------------
Reporter: tomchristie | Owner:
Type: New feature | julianapplebaum
Component: Core (Mail) | Status: assigned
Severity: Normal | Version:
Keywords: | Resolution:
Has patch: 1 | Triage Stage: Design
Needs tests: 0 | decision needed
Easy pickings: 0 | Needs documentation: 0
| Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by chuck-norris@…):

* cc: chuck-norris@… (added)


--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:20>

Django

unread,
Mar 25, 2013, 9:13:20 PM3/25/13
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+-------------------------------------------
Reporter: tomchristie | Owner: julianapplebaum
Type: New feature | Status: assigned
Component: Core (Mail) | Version:

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------
Changes (by carljm):

* needs_better_patch: 0 => 1
* needs_tests: 0 => 1
* stage: Design decision needed => Accepted


Comment:

Rendering a template is simple, but there are some minor gotchas in
templated email (like remembering to remove newlines from the rendered
subject template) that would be reasonable to put in a convenience
function in Django rather than requiring everyone to implement them
independently. And the `EmailMultiAlternatives` API is just enough
boilerplate to always require looking up in the docs.

IMO the blocks approach implemented above (both in the patch and the
linked external project) is too complex, too much code, and too unusual a
use of templates (blocks are for template inheritance, not a way to
combine multiple templates in one file.) I would rather favor a simple
extension naming convention (i.e. give `path/to/myemail` and it looks for
templates `path/to/myemail.txt`, `path/to/myemail.html`, and
`path/to/myemail.subject.txt`). I've attached a sample implementation of
this approach (not yet integrated as a patch to Django); it really isn't
very much code. (This implements a two-layer API, with both a
`send_multipart` function that accepts strings, and a
`send_templated_multipart` that does the template-finding and rendering.)

I guess I'm personally +0 or +0.5 on including something like this in
Django. I think it's a very common pattern that's just irritating enough
to re-implement to be worth considering for inclusion, but I won't mind at
all if another core dev decides to close this wontfix.

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:21>

Django

unread,
Mar 25, 2013, 9:15:53 PM3/25/13
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+-------------------------------------------
Reporter: tomchristie | Owner: julianapplebaum
Type: New feature | Status: assigned
Component: Core (Mail) | Version:

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------
Changes (by carljm):

* needs_docs: 0 => 1


--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:22>

Django

unread,
Mar 26, 2013, 1:44:49 PM3/26/13
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+-------------------------------------------
Reporter: tomchristie | Owner: julianapplebaum
Type: New feature | Status: assigned
Component: Core (Mail) | Version:

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------

Comment (by artem.rizhov@…):

> too unusual a use of templates (blocks are for template inheritance, not
a way to combine multiple templates in one file.)

Maybe you are right. However 3 files per message is too many. It may be
hard and annoying to maintain so many files. And somebody may forget to
change one of templates.

And why you say "multiple templates"? Imho this is single template of
multipart message :) Let's add this at the top of template:

{{{
{% extends 'email/multipart.html' %}
}}}

Does it look better now? ;) We also may add 'email/text.html',
'email/html.html' and so on. This will make the template code looking more
usual.

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:23>

Django

unread,
Mar 26, 2013, 1:57:16 PM3/26/13
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+-------------------------------------------
Reporter: tomchristie | Owner: julianapplebaum
Type: New feature | Status: assigned
Component: Core (Mail) | Version:

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------

Comment (by carljm):

If the implementation requires Python code pulling out the blocks from the
rendered template for individual specialized handling, then IMO it's a
misuse of template blocks and it should be separate templates instead. If
the hypothetical `email/multipart.html` base actually contained a full
template for a multipart message, that would be a reasonable use of
templates (but still not necessarily a good idea, as the template would
then be re-implementing things already handled by
`EmailMultiAlternatives`).

I don't buy the idea that maintaining three files is too hard. But for
people who feel that way, alternative approaches would always be available
as third-party packages. (Or we can just wontfix this and let all
implementations stay outside core, I'm fine with that too.)

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:24>

Django

unread,
Mar 26, 2013, 2:23:23 PM3/26/13
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+-------------------------------------------
Reporter: tomchristie | Owner: julianapplebaum
Type: New feature | Status: assigned
Component: Core (Mail) | Version:

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------

Comment (by anonymous):

> Or we can just wontfix this

Ok, you won :)

I hope it is possible to make both html and text vesrions not required.

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:25>

Django

unread,
Oct 14, 2013, 11:56:44 AM10/14/13
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+-------------------------------------------
Reporter: tomchristie | Owner: julianapplebaum
Type: New feature | Status: closed
Component: Core (Mail) | Version:
Severity: Normal | Resolution: duplicate

Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------
Changes (by timo):

* status: assigned => closed
* resolution: => duplicate


Comment:

Marking this as a duplicate of #20817 which added an `html_message`
parameter to `send_mail()`.

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:26>

Django

unread,
Oct 14, 2013, 12:06:50 PM10/14/13
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+-------------------------------------------
Reporter: tomchristie | Owner: julianapplebaum
Type: New feature | Status: closed
Component: Core (Mail) | Version:
Severity: Normal | Resolution: duplicate
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------

Comment (by anonymous):

timo, does `html_message` parameter allow django templates to be used?

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:27>

Django

unread,
Oct 14, 2013, 1:43:19 PM10/14/13
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+-------------------------------------------
Reporter: tomchristie | Owner: julianapplebaum
Type: New feature | Status: closed
Component: Core (Mail) | Version:
Severity: Normal | Resolution: duplicate
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------

Comment (by charettes):

@anon yes, you could use the
[https://docs.djangoproject.com/en/dev/ref/templates/api/#the-render-to-
string-shortcut render_to_string] function to build the `html_message`
kwarg passed to `send_mail`.

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:28>

Django

unread,
Oct 15, 2013, 4:52:45 AM10/15/13
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+-------------------------------------------
Reporter: tomchristie | Owner: julianapplebaum
Type: New feature | Status: new

Component: Core (Mail) | Version:
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------
Changes (by mjtamlyn):

* status: closed => new
* resolution: duplicate =>


Comment:

No, this does not close the original OPs request, and concept as mentioned
by Carl.

This ticket is to introduce a helper function of some sort to handle
`send_mail(render_to_string(...))`. It's just a helper function, it's
achievable without, but it's an exceedingly common pattern and personally
I'm +1 on having this. A significant number of projects I've worked on
have included a utility function named something like
`render_to_send_mail()`.

The exact API is up for discussion still, which is probably the blocker
for this ticket. As mentioned in #20817, it may be better as extension
around the `EmailMessage` or `EmailMultiAlternatives` APIs rather than
just as a helper function. I can see something like the following API
being useful:

{{{
message = TemplatedEmail(
from_email=...,
to=[...],
subject_template='my_email_subject.txt',
body_template='my_email_template.txt',
html_body_template='my_enhanced_email_template.html',
context=context,
)
message.send()
}}}

A functional approach to this could be added as well as a shortcut
function, though this is already significantly easier than the existing
APIs to do this. If we take Carl's earlier suggestion about a naming
convention, it becomes simpler, alternatively we could add complexity by
also supporting kwargs for `subject`, `body` and `html_body` which can
take rendered strings as alternatives.

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:29>

Django

unread,
Feb 4, 2015, 3:32:46 PM2/4/15
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+-------------------------------------------
Reporter: tomchristie | Owner: julianapplebaum
Type: New feature | Status: new
Component: Core (Mail) | Version:
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------
Changes (by collinanderson):

* cc: cmawebsite@… (added)


--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:30>

Django

unread,
Feb 4, 2015, 3:36:10 PM2/4/15
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+-------------------------------------------
Reporter: tomchristie | Owner: julianapplebaum
Type: New feature | Status: new
Component: Core (Mail) | Version:
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------
Description changed by timgraham:

Old description:

> If your sending email it's likely that you want to render the body text
> from template, but there's currently no shortcut to send an email based
> on a template.
>
> The attached patch is based on a stripped down version of
> https://github.com/bradwhittington/django-templated-email
>
> It adds `django.shortcuts.send_templated_mail`, which mirrors the
> existing `send_mail`, but which renders the subject and body of the mail
> from a template, rather than taking their values explicitly. It also
> supports multipart html/plaintext emails.
>
> The docs will look something like this...
>
> **send_templated_mail(template_name, from_email, recipient_list,
> dictionary=None, context_instance=None, fail_silently=False,
> auth_user=None, auth_password=None, connection=None):**
> Sends a mail, rendering the subject and body of the email from a
> template.
>
> The template should contain a block named 'subject', and either/both
> of a 'plain' and/or 'html' block.
>
> If only the 'plain' block exists, a plaintext email will be sent.
>
> If only the 'html' block exists, the plaintext component will be
> automatically generated from the html, and a multipart email will be
> sent.
>
> If both the 'plain' and 'html' blocks exist, a multipart email will
> be sent.
>
> **Required arguments:**
>
> `template_name` - The template that should be used to render the
> email.
>
> `from_email` - The sender's email address.
>
> `recipient_list` - A list of reciepient's email addresses.
>
> **Optional arguments:**
>
> `dictionary` - The context dictionary used to render the template. By
> default, this is an empty dictionary.
>
> `context_instance` - The Context instance used to render the
> template. By default, the template will be rendered with a Context
> instance (filled with values from dictionary).
>
> `fail_silently` - As in `send_mail`.
>
> `auth_user` - As in `send_mail`.
>
> `auth_password` - As in `send_mail`.
>
> `connection` - As in `send_mail`.

New description:

If your sending email it's likely that you want to render the body text
from template, but there's currently no shortcut to send an email based on
a template.

The attached patch is based on a stripped down version of
https://github.com/bradwhittington/django-templated-email

It adds `django.shortcuts.send_templated_mail`, which mirrors the existing
`send_mail`, but which renders the subject and body of the mail from a
template, rather than taking their values explicitly. It also supports
multipart html/plaintext emails.

The docs will look something like this...
{{{
**send_templated_mail(template_name, from_email, recipient_list,
dictionary=None, context_instance=None, fail_silently=False,
auth_user=None, auth_password=None, connection=None):**
Sends a mail, rendering the subject and body of the email from a
template.

The template should contain a block named 'subject', and either/both
of a 'plain' and/or 'html' block.

If only the 'plain' block exists, a plaintext email will be sent.

If only the 'html' block exists, the plaintext component will be
automatically generated from the html, and a multipart email will be sent.

If both the 'plain' and 'html' blocks exist, a multipart email will be
sent.

**Required arguments:**

`template_name` - The template that should be used to render the
email.

`from_email` - The sender's email address.

`recipient_list` - A list of reciepient's email addresses.

**Optional arguments:**

`dictionary` - The context dictionary used to render the template. By
default, this is an empty dictionary.

`context_instance` - The Context instance used to render the template.
By default, the template will be rendered with a Context instance (filled
with values from dictionary).

`fail_silently` - As in `send_mail`.

`auth_user` - As in `send_mail`.

`auth_password` - As in `send_mail`.

`connection` - As in `send_mail`.
}}}

--

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:31>

Django

unread,
Feb 4, 2015, 3:54:31 PM2/4/15
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+-------------------------------------------
Reporter: tomchristie | Owner: julianapplebaum
Type: New feature | Status: new
Component: Core (Mail) | Version:
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------

Comment (by carljm):

With the addition of the `html_message` parameter to `send_mail`, the
reasons for adding this have been reduced to:

1. Saving the need to type `render_to_string` two or three times.
2. Saving the need to collapse newlines in the rendered subject (though
I'm not actually sure off-hand what the consequence of failing to do that
is, would need to check).

That starts to look a bit thin as rationale, but it is a common enough
need that I'd probably still be at least +0 on adding it.

I think the naming-convention suggestion is probably a bit too implicit
for Django's usual API style; that's something probably better left to a
third-party solution.

So I think if we do this, the API should probably look something like what
Marc proposed.

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:32>

Django

unread,
Feb 4, 2015, 3:55:31 PM2/4/15
to django-...@googlegroups.com
#17193: Send templated email.
-----------------------------+-------------------------------------------
Reporter: tomchristie | Owner: julianapplebaum
Type: New feature | Status: new
Component: Core (Mail) | Version:
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------

Comment (by carljm):

Also, one more argument against the "single template and pull out blocks"
suggestion -- a single file with some portions that are HTML and some
portions that are text does not work well with editor modes and syntax
highlighting.

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:33>

Django

unread,
Jan 29, 2022, 5:31:35 PM1/29/22
to django-...@googlegroups.com
#17193: Send templated email.
------------------------------+-------------------------------------------
Reporter: Tom Christie | Owner: julianapplebaum

Type: New feature | Status: new
Component: Core (Mail) | Version:
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
------------------------------+-------------------------------------------

Comment (by Jacob Rief):

Just in case someone wants to implement a template rendering system for
the email backend, I have added a templated based email renderer to
https://github.com/ui/django-post_office

--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:34>

Django

unread,
Jun 23, 2024, 3:57:47 PM6/23/24
to django-...@googlegroups.com
#17193: Send templated email.
------------------------------+-------------------------------------------
Reporter: Tom Christie | Owner: julianapplebaum
Type: New feature | Status: new
Component: Core (Mail) | Version:
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
------------------------------+-------------------------------------------
Comment (by Mike Edmunds):

There are at least three third-party packages that provide this
functionality (in various states of maintenance):

- https://pypi.org/project/django-templated-mail/
- https://pypi.org/project/django-mail-templated/
- https://pypi.org/project/django-mail-templated-simple/
--
Ticket URL: <https://code.djangoproject.com/ticket/17193#comment:35>
Reply all
Reply to author
Forward
0 new messages