Markdown image handling in Django
It’s an interesting question: how to deal with images in django admin which claims to be hardly extensible.
The default package comes with markdown integration, which could be easily installed by obtaining python-markdown from your favorite package manager.
Next, we should attach images to the record. We’ll do that by embedding special model of entry-specific image. To do the markdown, we need to have images’ paths or reference them in some way. The spec says we can invoke reference by ![][ref_id] and then it’ll be substituted.
def get_markdown(self):
# create instance of Markdown class (note capital "M")
md = markdown.Markdown()
for image in self.chapterimage_set.all():
image_url = settings.MEDIA_URL + image.image.url
# append image reference to Markdown instance
# md.reference[id] = (url, title)
title = image.title
md.references[title.lower()] = (image_url, '')
# parse source text
convert = md.convert(self.body)
refs = md.references
# assert False
return convert
Here we’ll notice the .lower() call. At first, I was surprised by selected action of the method, and after reading the source code on github, I got it! Assert false is a handy piece of code to fire up debug panel!
class ReferencePattern(LinkPattern):
""" Match to a stored reference and return link element. """
NEWLINE_CLEANUP_RE = re.compile(r'[ ]?\n', re.MULTILINE)
def handleMatch(self, m):
try:
id = m.group(9).lower()
except IndexError:
id = None
if not id:
# if we got something like "[Google][]" or "[Goggle]"
# we'll use "google" as the id
id = m.group(2).lower()
# Clean up linebreaks in id
id = self.NEWLINE_CLEANUP_RE.sub(' ', id)
if not id in self.markdown.references: # ignore undefined refs
return None
href, title = self.markdown.references[id]
text = m.group(2)
return self.makeTag(href, title, text)
def makeTag(self, href, title, text):
el = util.etree.Element('a')
el.set('href', self.sanitize_url(href))
if title:
el.set('title', title)
el.text = text
return el
class ImageReferencePattern(ReferencePattern):
""" Match to a stored reference and return img element. """
def makeTag(self, href, title, text):
el = util.etree.Element("img")
el.set("src", self.sanitize_url(href))
if title:
el.set("title", title)
el.set("alt", text)
return el
It’s then used in a new way when invoked in template:
{# {{ chapter.body|markdown }}#}
{{ chapter.get_markdown|safe}}
Comments