Release of LifeFlow 0.91

July 7, 2008. Filed under lifeflow 20

About three weeks later than my imagined release date, LifeFlow 0.91 is finally ready for release. There are a number of small improvements that have gone on to make LifeFlow more usable and flexible. The code has improved in a number of places, although it still has many places where it can stand to be improved. Lets start out by taking a look at some of the improvements and changes.

Improvements in 0.91

  1. Added support for incorporating snippets of non-Markdown markup into entries, including Textile, ReST, and HTML. This functionality is accessed like this:

    Do whatever in textile.

    or like this

    A document in ReST formatting.

    and completely unmangled HTML can be included like this

    <script> alert('bah'); </script>

    Please note that the Textile and ReST rendering rely on your location installations of the Textile Python module and Docutils modules respectively, so you will need to install those before taking advantage of the rendering. If they are not installed (or you use an unsupported name for a block such as ~~~magic then it will injected into the document completely untouched (just as like the HTML injection example above.)

    It would be very easy to extend this functionality (contained in lifeflow/markdown/ to render other types of formatting, if any others seem appropriate.

  2. Rageev Sebastian contributed an excellent patch to the code syntax highlighter, so that it now works properly at non-base levels of indention. This means that code syntax highlighting can now play nicely within lists (like the example just below), as well as any other tomfoolery you might attempt.

    var person = {};
    person['name'] = "Will";
    person['age'] = 22;
    person['hobbies'] = ['programming','basketball','riding on trains'];

    This also means that adding syntax coloring to an existing Markdown document is now far simpler. Instead of reindenting all code to be relative to the base level of indentation, it is sufficient to add @@ common-lisp (or whatever the appropriate language lexer is) at the beginning of the indention block, and add @@ at the end of the indention block.

  3. Added support for line numbering for syntax colored code snippets. To take advantage of this functionality simply add table or inline following the language declaraton for a syntax colored block. For example @@ ruby table or @@ java inline. Respectively table and inline look like this:

    def double(x):
        return x * x
    y = 10
    z = double(y)
    a = double(double(double(z)))


    1 def double(x):
    2     return x * x
    4 y = 10
    5 z = double(y)
    6 a = double(double(double(z)))

    I realize the number-line alignment is a bit off for the table line numbers, but I am slightly baffled at what is causing it (even playing dirty didn't help me conquer this CSS). Also, I am well aware that the inline version is completely unfriendly about copy-pasting. The line numbering is being done by exposing a bit more of Pygment's functionality, as opposed to an implementation of my own, so I am still considering how to go about improving upon these options.

  4. Courtesy of Luke Hatcher, RSS Feeds now include the date and time they were published.

  5. Pre and code tags now use fixed width fonts, fixing one of many braindead CSS problems. (And contributing to the CSS odities in the table based syntax coloring line numbers.)

  6. Improved the quality of the inlined help for LifeFlow specific Markdown extensions and for generic Markdown as well. It still has a ways to go, but at this point its helpful enough that I find myself consulting it for some of the LifeFlow specific magery.

  7. A number of template and CSS tweaks to improve the appearance of the forward facing pieces of LifeFlow. Many of these were inspired by commentary and suggestions by Kenneth Arnold.

  8. Can edit comments in LifeFlow Editor.

  9. Can edit the current Django site within LifeFlow Editor. The Django site is used for defining the URL used in certain components of the framework (such as RSS feeds).

  10. Can modify sites to ping (typically blog aggregators such as Ping-O-Matic, but could be almost anything you want to notify of your entry being published. from within LifeFlow Editor.

  11. Lots of refactoring and general improvements of the quality of code. This goes from the simple like using a regex based sluggify method suggested by Peter Burns, to replacing numerous instances of manual pagination with the QuerySetPaginator. There are still some pain spots in the code, in particular still performs the awkward 'double save' in order to properly setup many to many relationships which are necessary for rendering articles' markup. That said, the quality of the code is moving in a better direction, and will continue to improve.

Downloadable Zip

Although the recommended way for getting LifeFlow is still grabbing a copy from its Git repository (explained just below), from now own I will also create zips of releases. This zips will include two directories:

  1. A project directory, which will include a standard Django project with LifeFlow setup.
  2. A lifeflow directory, which will include the Lifeflow project.

You can grab the 0.91 Release Zip here

The settings will be for a no-effort development copy, and will have to be tweaked to be applicable for a public facing deployment. In particular, it will be configured as follows:

  1. It will use an SQLite3 database (which will use the os.path module to create itself in the project folder).
  2. It will use the Django development file server to serve media.

Setting up the development copy will be as painless as possible:

  1. Unzip the zipped release.

  2. Add the lifeflow folder to your Python path.

  3. Go into the project folder, and run python syncdb.

  4. Edit project/ to suit your setup. Here are the important ones:

    1. LIFEFLOW_* need to be customized for your blog.

    2. MEDIA_ROOT needs to be the absolute path to your lifeflow/media/ folder. For example, mine looks like

      MEDIA_ROOT = '/Users/username/git/lifeflow/media'

    3. TEMPLATE_DIRS must have the lifeflow/templates folder added to its tuple of directories. For example, mine looks like:


  5. Run the devel server as you normally would: python runserver.

At that point you should now be able to write articles and manage your deployment at, and visit your blog at

Cloning from Repository

You can grab the most current copy of LifeFlow by visiting its Git repository at GitHub. If you haven't tried out Git yet, it can be a bit of a pain to get it running on your computer (well, it was for me since the copies in the OSX package managers didn't install successfully on my computer), but its well worth it.

The easiest way to get started quickly with the current version is to download the above zip file, but don't follow step two (don't add the lifeflow folder in the zip to your Python path), instead clone a copy from the git repository:

git clone git://

and then add that checkout folder lifeflow folder to your Python path. From there its extremely easy to make changes to your local copy. If you make any interesting or helpful changes, please make your repository available and I'll pull the changes in and incorporate them (or you could use git send-email, although the documentation seems slightly intimidating).

Upcoming Changes and Improvements

LifeFlow 0.92 is going to be a fun release, and is focused on what I am tentatively calling text wizardry, but might more accurately be called text manipulation or simply text stuff. The focus is going to be on adding convenient hooks for text pre and post parsers, such that ambitious users can extend LifeFlow to do pretty much anything with their text. One example would be creating links to Wikipedia for the first mention of a list of terms. These ideas are still on the drawing board, but should open up a whole new can of worms of potential.

Further in the future other features being planned include: adding a number of user permission models (editors, writers and admins to start with) to support a complex multi-user workflow, and a cleanup of the LifeFlow Editor to make it more consistent and less complex.