Now with pretty colours...
Posted 2009-01-27 23:14:50 by Oisin.

I've abstracted out the "Basic apps blog" and wrapped it in my own app called 'Musings'. Its not yet at a point where I might consider rolling my own. However I had to do this in order to gain more control over searching, the data returned and the templates in my site. I've also added unit tests to cover the functionality my 'Musings' app is providing.

I'm not a fan of the templates knowing too much about the database and the relationship that entries have to each other. This is something I've noticed in Django and the apps I've looked at so far. It seems to be accepted practice to use database entries directly. For example the basic blog provides a Post entry which can have an Author entry. To access the authors name you might do the following in a template:

1
<em>Author: {{post_object.author.first_name}} post_object.author.last_name</em>

I don't like this at all as it leads to tight coupling which is just bad. Any change to the database would require changes to the template. On a small project that might be ok, however on a large project particularly one without any unit/acceptance testing its a no-no. To allow me to use other blog backends in future I've wrapped what gets returned to hide these relationships and provide only what is needed.

1
<em>Author: {{post_object.author_name}}</em>

I've finally managed to get ReStructuredText markup working along with a custom "sourcecode" directive. This uses Pygments to highlight the source code and includes lines numbers. The code I've used to do this is shown below. Its being marked up by itself ;)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
"""
Provide a custom directive for the ReStructuredText I'm using in my blog.

Based on the 'django-rstify' http://code.google.com/p/django-rstify/ by
George Brandl, who released it under the BSD license. I've modified
it a lot to my needs. I've mainly made it less django-centric so I can
use it elsewhere. I'm releasing this code  under the BSD License.

Pygments must also be installed for this to work http://pygments.org/

Oisin Mulvihill
2009-01-27

"""
from docutils import nodes
from docutils.core import publish_parts
from docutils.parsers.rst import directives
from docutils.parsers.rst import Directive

from pygments import highlight
from pygments.formatters import HtmlFormatter
from pygments.lexers import get_lexer_by_name, TextLexer


class SourceCode(Directive):
    """My custom sourcecode directive markup using pygments.

    For example:

    .. sourcecode:: python

          import sys

          def sayhello(msg):
            print 'Hello  %s' % msg

          sayhello('Bob')
          sys.exit(0)

    This will result in highlighted code with line numbers,
    with the css styles done inline.

    """
    required_arguments = 1
    optional_arguments = 0
    final_argument_whitespace = True
    option_spec = {}
    has_content = True

    def run(self):
        """Generate sourcecode highlighting based on pygments.
        """
        # noclasses=True use inline styles.
        formatter = HtmlFormatter(noclasses=True, linenos=True)

        try:
            lexer = get_lexer_by_name(self.arguments[0])
        except ValueError:
            # no lexer found - use the text one instead of an exception
            lexer = TextLexer()

        parsed = highlight(u'\n'.join(self.content), lexer, formatter)

        return [nodes.raw('', parsed, format='html')]


def rstify(data):
    """Convert the given restructured text into a html fragment
    ready for insertion elsewhere.

    data:
       This must be text which is valid ReStructuredText.

    Returned:
       A string containing a html fragment representing the
       convert restructured data. Errors in processing will
       also be displayed in the string.

    This function registers special directives which can be
    used.

    .. sourcecode:: <Language e.g. python>

      code line 1 ...
      code line 2 ...
      :
      etc

    """
    directives.register_directive('sourcecode', SourceCode)

    parts = publish_parts(data, writer_name='html')

    return parts['body']