Django Tech Blog is now running my blog. It is only fitting that my first post on the new system is about the technology behind it.

I never intended to compete with Wordpress on number of features, and Techblog was never intended to be an all-things-to-everyone type of web application, but I can boast a few features that set it apart. I'll cover some of those features in future posts, for now I would like to go over the light-weight markup language I use for posts.

I've noticed that when working on, and other content driven sites, that adding additional content to a page was always a major under-taking. Adding a new content area to a page typically required adding a field to the model and some interface work. I figured it would be nice to build a generic system where the various pieces of content are stored in a single field in the database and created as required.

I guess that XML would be the obvious choice for such a system, but writing XML is best left to machines – in my opinion. Rather, I settled on a simple markup that I call extended-postmarkup.

In an extended-markup post, the text is divided up in to sections, which are ultimately transformed in to HTML and inserted in the page. Each section consists of one or more chunks, which are a collection of lines that are passed through a specified Django template. The default chunk template passes the lines to a bbcode filter and turns each line in to a paragraph, but any other kind of text processing could be done.

A line in the markup is parsed as an extended-markup directive if it begins with a { character and ends with a } character. A new section is introduced with a directive that begins with a . character followed by the name of the section, chunks are introduced with two . characters. The name of a chunk maps directly to the name of a Django template. For instance the {..code} chunk directive causes the subsequent lines to be rendered with markupchunks/code.html which does syntax highlighting.

Here's an example of some simple extended markup:

This is the [b]main body[/b] of the post, and will be turned in to paragraphs.

print "Hello, World!"

Back to paragraphs again.

<blink>There is also raw HTML if you must!</blink>

This goes in the second column.

This goes in the footer.

The code above introduces some other abilities of extended markup. The {..language=python} directive sets a chunk variable, which is also passed to the chunk template; in the code above it is the name of the language to do syntax highlighting, but there can be any number of key/value pairs set for chunks. There is also a chunk directive with no name ({..}), this sets the chunk type back to the default.

… this simple system means I can create ad-hoc features in a post such as pull-quotes

That's all there is to authoring extended-markup, but this simple system means I can create ad-hoc features in a post such as pull-quotes, and even use different markups such as markdownand reStructuredText.

Here is another example, used in this post to create the list of links you should be able to see at the top of the right-hand column.

{..title=An example links list}
My blog|
Planet Python|

The markup is not limited to the visible parts of the site; in this blog there are sections marked out for CSS and Javascript, so I can make style tweaks and demonstrate Javascript techniques without having to link to an external page. This is a techblog after all…

If you want to play with the code, head over to the django-techblogproject page on Google Code. It is completely lacking in documentation or comments, but that may improve in the future.

That's all for now, I'll write up more techblog features in the coming days. I'll also be doing a lot more blogging on other topics, as I need to be able to justify to myself, spending 4 months of spare-time on this!

This blog post was posted to It's All Geek to Me on Wednesday February 25th, 2009 at 9:13PM

19 Responses to "Django Techblog markup system"

  • Joe
    February 26th, 2009, 4:37 p.m.

    Thanks for sharing the code & explanation behind the work.

    Side note –

    I noticed you keep copies of jquery in the trunk. You may want to consider using jquery hosted @ google []

    – joe

  • Lucas
    February 26th, 2009, 5:51 p.m.

    Hey great job, i like the extended-markup. It seems really friendly to use.

  • February 26th, 2009, 9:54 p.m.

    Joe, good idea – I have let Google host JQuery for me.

    Lucas, thanks.

  • February 26th, 2009, 10:53 p.m.

    Nice job.

    I have been thinking ahout coding something like this for awhile.

    Thanks for sharing the code

    Looking forward to try it out.

    lzantal []

  • June 12th, 2009, 2:21 p.m.

    hi, thanks for provide a such great code, but , would you pls tell me how to add the “Home/About/Contact” at the top ? thanks very much

  • June 12th, 2009, 2:42 p.m.

    That's done with the description extended-markup, which you can enter via the admin section. Just type it in to the ‘description’ box.

    Here's the my description for this blog.




    <a href="[url][/url]" target="_blank">
    <img src="[url][/url]">

    My name is [b][url /about/]Will McGugan[/url][/b]. I am an unabashed [i]geek[/i], an author, a [i]hacker[/i] and a Python expert -- amongst other things!

    You are reading my [i]tech[/i] blog. See the [url /]homepage[/url] for my other blogs.







    The bit you are interested in is the mainlinks section at the top.

  • June 12th, 2009, 2:54 p.m.

    ha, i see , just now i use


    then it in the wrong position

    thank you :-)

  • June 13th, 2009, 1:09 p.m.

    hi, would you please tech me how to let the index only show the summary of the article, which kind of extendmarkup i can use , or where i can find the extendmarkup i can use in this pretty work. thanks a lot.

  • June 13th, 2009, 2:56 p.m.

    i have try:




    but it take no effect :-(

  • June 13th, 2009, 3:14 p.m.

    Atree, I'm afraid there is no documentation as yet.

    You were on the right lines, here is how to do the summary:


    Everything up to that point is the summary.

    For the other tags, take a look at techblog/markup/templates/markupchunks. Let me know if you have any questions…

  • July 3rd, 2009, 1:18 p.m.

    hi,will, thanks for your last reply. and i have another question that how do i add a microblog, thanks :-)

  • July 3rd, 2009, 1:31 p.m.

    Atree, add the details via the admin site. You also need to select which blog (or channel) the tweets will be posted to.

    Then you need to set up a cron job that polls every 15 minutes or so. The cron job should run the ‘updateblog’ manage command.

    Don't forget to post the link to your blog so I can check it out!

  • July 3rd, 2009, 1:50 p.m.

    will,thanks ! there is a doubt that i do not know what to fill in the Template path, the project's template path? or other?

  • July 3rd, 2009, 2:06 p.m.

    Its a path to a django template, I use “blog/posts/microblog/”, which should probably be the default. But you can change it so that you can render microblogs differently from other posts.

  • angela
    July 9th, 2009, 7:10 p.m.

    Will, thanks this is great. It's going to save me the time of starting from scratch! and I just wanted to add that in looking through the code I noticed your 404 and it's now one of my top five - hilarious!

  • July 9th, 2009, 7:48 p.m.

    Glad you find it useful, Angela! You should see the 500 page. []

  • October 12th, 2009, 12:37 p.m.

    Will, thanks for the code. I'm just starting to get to grips with django and wanted to code my own cms/blog. Your code will teach me a lot as I try and roll my own.

  • October 12th, 2009, 9:48 p.m.

    Ian, glad you find it useful!

  • December 21st, 2009, 4:34 a.m.

    i'm a new starter django (but better python) developer. your blog system seems great. i got the code from svn. i wonder, when you will release it?

Leave a Comment

You can use bbcode in the comment: e.g. [b]This is bold[/b], [url][/url], [code python]import this[/code]
Preview Posting...
Previewing comment, please wait a moment...
An example links list
Will McGugan

My name is Will McGugan. I am an unabashed geek, an author, a hacker and a Python expert – amongst other things!

You are reading my tech blog. See the homepage for my other blogs.

Search for Posts
Possibly related posts
Popular Tags
Recent Comments
Why another framework? what wrong with django, pyramid, flask?will be have answer for this question in the docs)
Hi! Really great code, good work! But trying to use it on a responsive site, it didn't resize images. So, ...
using of a recursion: def thousands_with_commas(i): def _recurse(n): x, y = divmod(n, 1000) if x 1000: return [x, y] return ...
#1 import string from collections import Counter def tagwords(): tagcounter = Counter() with open(tagwords.txt, r) as wordfile: words = list(filter(None, ...
- the jeffster on Python Coder Test
This is because mod_wsgi does not pass OS environment variables to the underlying application by default
© 2008 Will McGugan.

A technoblog blog, design by Will McGugan