Search code examples
pythondjangodjango-email

Django – generate a plain text version of an html email


I want to improve deliverability rates by providing both text-only and html versions of emails:

text_content = ???
html_content = ???

msg = EmailMultiAlternatives(subject, text_content, 'from@site.com', ['to@site.com'])
msg.attach_alternative(html_content, "text/html")
msg.send()

How can I do this without duplicating email templates?


Solution

  • Here is a solution:

    import re
    from django.utils.html import strip_tags
    
    def textify(html):
        # Remove html tags and continuous whitespaces 
        text_only = re.sub('[ \t]+', ' ', strip_tags(html))
        # Strip single spaces in the beginning of each line
        return text_only.replace('\n ', '\n').strip()
    
    html = render_to_string('email/confirmation.html', {
        'foo': 'hello',
        'bar': 'world',
    })
    text = textify(html)
    

    The idea is to use strip_tags to remove html tags and to strip all extra whitespaces while preserving newlines.

    This is how the result will look like:

    <div style="width:600px; padding:20px;">
        <p>Hello,</p>
        <br>
        <p>Lorem ipsum</p>
        <p>Hello world</p> <br>
        <p> 
            Best regards, <br>
            John Appleseed
        </p>
    </div>
    

    --->

    Hello,
    
    Lorem ipsum
    Hello world
    
    Best regards,
    John Appleseed