Snippet List
A variation on a theme, inspired by [snippet 39][39] and [snippet 119][119]. The
intent is to provide a more generic and simple mechanism for combining
[Markdown][markdown] with [Pygments][pygments]. Common scenarios could include blogging or commenting. Snippet 119 seemed too specific and perhaps not as
efficient, needing to process the HTML twice to accomplish it's ends. The one snag in the implementation is the need to use a tag other than `code` as a wrapper. See the comments for details.
You will need the [BeautifulSoup][soup] module installed.
Sample usage:
from django.db import models
class Blog(models.Model):
'''Bare bones blogging model'''
title = models.CharField(maxlength=255)
slug = models.SlugField(maxlength=255, prepopulate_from=('title',))
pub_date = models.DateTimeField()
# the cooked view, cached for quick retrieval
blog = models.TextField()
# the raw markdown-encoded text, saved for subsequent edits
markdown = models.TextField()
def save(self):
from datetime import datetime
if not self.id and not self.pub_date:
self.pub_date = datetime.now()
self.blog = pygmented_markdown(self.markdown)
super(Blog, self).save()
[39]: http://www.djangosnippets.org/snippets/39/
[119]: http://www.djangosnippets.org/snippets/119/
[soup]: http://www.crummy.com/software/BeautifulSoup/
[markdown]: http://www.freewisdom.org/projects/python-markdown/Installation
[pygments]: http://pygments.org/
- pygments
- beautifulsoup
- markdown
Python's [descriptor][1] protocol can seem a bit esoteric at first; however, it can
be invaluable in handling everyday idioms and patterns - something that the
Django framework authors have taken advantage of in numerous occasions
(e.g.: [auth middleware][2]).
One such idiom I see and use often and would like to generalize is the
attribute-existence check-or-set routine illustrated here:
def get_foo(self):
if not hasattr(self, '_foo'):
self._foo = init_foo()
return self._foo
Rather than coding this up multiple times (either for a given class or across
many unrelated classes), I would prefer to delegate this repetitive work to a
descriptor and remain [DRY][3]. The means to this end is implemented as a
variation on the Python `property` construct, and is intentionally over simplistic
(I leave the details of the heavy lifting up to the reader).
The basic premise shown in source here is simply straight-forward Python, a
quick and dirty example of how it could be utilized within a Django context is
shown here:
from django.db import models
from cacheprop import CacheProperty2
ARTIFACT_TYPES = (
('F', _('File')),
('D', _('Directory')),
('A', _('Alias')),
)
class Artifact(models.Model):
# model fields
name = models.CharField(maxlength=64)
type = models.CharField(maxlength=1, choices=ARTIFACT_TYPES)
file_metadata = CacheProperty2(
lambda self: self.filemetadata_set.get(artifact__id=self.id)
)
class FileMetadata(models.Model):
byte_size = models.IntegerField()
artifact = models.ForeignKey(Artifact, unique=True)
[1]: http://users.rcn.com/python/download/Descriptor.htm
[2]: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/middleware.py
[3]: http://c2.com/cgi/wiki?DontRepeatYourself
djypsy has posted 2 snippets.