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