How to programmatically send email in Plone
This document tells how to send email from Plone.
Email can be sent:
- manually, by calling MailHost;
- using a Content Rule (content rules have an email-out action by default) which can be activated by a workflow transition, for example;
- triggering email-based password reset.
Products.MailHost supports asynchronous sending in a separate thread via a mail queue.
Using a mail queue is recommended for production sites.
To enable the queue, go to the ZMI and the MailHost tool. Here, check the "Use mail queue" setting and set the "Queue directory". The queue directory is given as an absolute path on your server, must have a maildir layout (it needs the directories 'cur', new' and 'tmp' in it) and must be writeable by the system user, under which the Zope thread runs.
is prepared, sending it is as simple as:
try: host = getToolByName(self, 'MailHost') # The ``immediate`` parameter causes an email to be sent immediately # (if any error is raised) rather than sent at the transaction # boundary or queued for later delivery. return host.send(mail_text, immediate=True) except SMTPRecipientsRefused: # Don't disclose email address on failure raise SMTPRecipientsRefused('Recipient address rejected by server')
can be generated by calling a page template (
.pt) with keyword arguments. The values are accessed in
the template as
option/keyword. For example, take a sample template:
<tal:root define="lt string:<; gt string:>; dummy python:request.RESPONSE.setHeader('Content-Type', 'text/plain;; charset=%s' % options['charset']); member python:options['member'];" >From: "<span tal:replace="python:here.email_from_name" />" <span tal:replace="structure lt"/><span tal:replace="python:here.email_from_address" /><span tal:replace="structure gt"/> To: <span tal:replace="python:member.getProperty('email')" /> Subject: <span i18n:domain="yourproduct" i18n:translate="yoursubjectline" tal:omit-tag="">Subject Line</span> Content-Type: text/plain; charset=<span tal:replace="python:options['charset']" /> Dear <span tal:replace="member/getFullname" />: You can now log in as <span tal:replace="member/getId" /> at <span tal:replace="python:options['portal_url']" /> Cheers! The website team </tal:root>
This can be called with a
object and the
mail_template = portal.mail_template_id mail_text = mail_template(member=member, portal_url=portal.absolute_url(), charset=email_charset, request=REQUEST)
For more complete examples (with i18n support, etc.) see
the password reset modules (particularly
If you don't need to have third parties to override your email templates it might be cleaned to use Python string templates, as XML based TAL templates are not designed for plain text templating.
In the case SMTP server rejects the connection. etc. don't abort the current transaction (which is the default behavior)