[Answered ]-How to set default styles for Markdown in email

2👍

This is not something that can be done by Markdown itself. However, there are some Python libraries which will take HTML input (and some CSS) and output reformatted HTML with inline styles (as these answers point out). Therefore you would need to take the output of Markdown and pass it into one of those libraries.

As you are using a Django template filter (I’m assuming the filter rather than the Tag provided by Deux) to render the Markdown to HTML, you will need to create a second filter which wraps one of the CSS inliner libraries and pass the output of the Markdown filter to your custom filter. Your custom filter might look something like this (untested):

from django import template
from django.utils.safestring import mark_safe
from pynliner import Pynliner

register = template.Library()

@register.filter(name="html2email")
def pynliner_filter(value):
    css = "h1 {color:#eee; font-family:'Helvetica Neue'}"
    p = Pynliner()
    return mark_safe(p.from_string(value).with_cssString(css).run())

Then, in your template, you would do:

{{ myvar|markdown|html2email }}

It may be interesting to note that I hardcoded the CSS right in the filter. Expanding this to be customizable is left as an exercise for the reader. Fore more specific information on creating and loading custom template filters, see Django’s docs.


If you have styles defined in the template (in <style> tags), then those styles would presumably need to apply to the entire document (not just the part generated by Markdown). Note that the inliner tools will accept a complete HTML file (with CSS defined within it) and output a file which has those styles inlined. If that is your situation, then you will not need to use the custom template filter. Instead, after rendering the template, you will need to pass the HTML document through an inliner tool within your Django view. Perhaps something like this:

def someview(...)
    # Do your pre-template stuff here ...
    html = template.render()
    p = Pyliner()
    email_body = p.from_string(html).run()
    # Send your email here (or whatever you are doing) ...

Without more info about your specific situation, the above code leaves a lot out. Only the relevant bits to this specific issue are addressed. There is a lot more to have a working view. Although, if you already have a working view, then presumably you would only need to replace the line which renders the template with the few lines shown above.

👤Waylan

Leave a comment