February 25, 2009 will

Django Techblog markup system

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 ITProPortal.com, 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:

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

{..code}
{..language=python}
print "Hello, World!"

{..}
Back to paragraphs again.

{..html}
<blink>There is also raw HTML if you must!</blink>

{.column2}
This goes in the second column.

{.footer}
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.

{..linkslist}
{..priority=200}
{..title=An example links list}
My blog|http://www.willmcgugan.com
Planet Python|http://planet.python.org

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!

Use Markdown for formatting
*Italic* **Bold** `inline code`

Links to [Google](http://www.google.com)

> This is a quote
>

```python
import this
```
your comment will be previewed here
gravatar
Joe 7 years ago

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

http://encosia.com/2008/12/10/3-reasons-why-you-should-let-google-host-jquery-for-you/

– joe
gravatar
Lucas 7 years ago
Hey great job, i like the extended-markup. It seems really friendly to use.
gravatar
WIll McGugan 7 years ago
Joe, good idea – I have let Google host JQuery for me.

Lucas, thanks.
gravatar
lzantal 7 years ago
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
http://www.antalconsulting.com
gravatar
myreg 7 years ago
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
gravatar
Will McGugan 7 years ago
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.

{.mainlinks}

{..mainlinks}
Home|/blog/tech/
About|/about/
Contact|/contact/
Projects|/projects/


{.column2}


{..html}
<a href="http://twitter.com/willmcgugan" target="_blank">
<img src="http://www.willmcgugan.com/media/uploads/images/twitter.png">
</a>


{..}
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.



{..}
{..module=search}


{..}
{..module=relatedposts}
{..count=5}

{..}
{..module=tags}


{..}
{..module=populartags}
{..count=10}

{..}
{..module=archives}

{..}
{..module=recentcomments}
{..count=5}

The bit you are interested in is the mainlinks section at the top.
gravatar
myreg 7 years ago
{.mainlinks}
{..mainlinks}
Home|/blog/tech/
About|/about/
Contact|/contact/
Projects|/projects/

ha, i see , just now i use
{..}
{..mainlinks}
.....
then it in the wrong position

thank you :-)
gravatar
atree 7 years ago
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.
gravatar
atree 7 years ago
i have try:
{..summary}
{..}

and:



but it take no effect :-(
gravatar
Will McGugan 7 years ago
Atree, I'm afraid there is no documentation as yet.

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

{..more}
{..}

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…


gravatar
atree 7 years ago
hi,will, thanks for your last reply. and i have another question that how do i add a microblog, thanks :-)
gravatar
will 7 years ago
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!
gravatar
atree 7 years ago
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?
gravatar
Will 7 years ago
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.
gravatar
angela 7 years ago
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!
gravatar
Will McGugan 7 years ago
Glad you find it useful, Angela! You should see the 500 page. http://www.willmcgugan.com/bad/
gravatar
Ian McConachie 6 years ago
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.
gravatar
Will McGugan 6 years ago
Ian, glad you find it useful!
gravatar
Mustafa Yılmaz 6 years ago
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?