Installing a Development Deployment of LifeFlow, a Django Blog Solution

January 7, 2008. Filed under django 72 lifeflow 20 blog 14 install 1

After the recent LifeFlow sprint I have been heading, now is the time for me to finally sit down and write a series of articles on installing LifeFlow for people who are not me. I say series not because it is hard to install, but because I envision a progression along these lines:

  1. A tutorial for installing a local development copy for people who are already comfortable with Django.
  2. An extended version of the same tutorial, but more indepth for newcomers to Django.
  3. Looking at deploying LifeFlow on a virtual or real server where you have root access.
  4. Looking at deploying LifeFlow on DreamHost.

This is the first article in that intended series: installing a development setup of LifeFlow for people who are already comfortable with Django (note: this entry contains everything a seasoned Django user needs to know to deploy a production version of LifeFlow, but it doesn't go out of its way to connect the production dots. A more explicit tutorial on that topic will be forthcoming).


First, LifeFlow is operating using the SVN trunk of Django. Unfortunately, it won't work with anything earlier. Once Django 1.0 arrives there will be a 1.0 version of LifeFlow, but at this point it only plays nicely with trunk.

Next you will need to install two Python libraries: pygments and markdown. The easiest way to do that is:

easy_install pygments
easy_install markdown

Check Out Code

The first step is to grab a copy of LifeFlow from SVN.

svn co

Next you need to make the checkout accessible by Python. You'll need to figure out where your site-library is:

python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"

and then symbolically link lifeflow there:

ln -s `pwd`/lifeflow /somewhere/site-library/lifeflow

Then you need to verify that your symlink is correct. Launch a Python interpreter and try:

import lifeflow

If there aren't any errors thrown then everything is okay. If there are some errors thrown, then you'll need to take a look in your site-library and see if lifeflow is there, and try to figure out what went wrong (probably a typo).

Making a Django Project

Next we need to make a project for LifeFlow to live in (LF is only a Django app, not a project). startproject blog

If you don't have in your system path, then you may have to locate it. It is in the django/bin folder in your Django checkout.

Now we need to edit the file in our newly created project.

First you need to setup a database. Because this is a development setup, I use sqlite3 for ease of use. (You'll need to change the path on your install to a folder that exists on your system.)

DATABASE_NAME = '/Users/will/django/blog/db.db'

Here are other changes you will need to make (keep in mind that MEDIA_ROOT and TEMPLATE_DIRS will have to be adapted to your checkout, as they probably don't exist in the same place as mine):

LOGIN_URL = "/editor/login/"
LOGOUT_URL = "/editor/logout/"
MEDIA_ROOT = '/Users/will/django/lifeflow/trunk/lifeflow/media'
# This is because we'll be using the development file
# server to serve our static media, and it gets confused
# sometimes if we don't do this
ADMIN_MEDIA_PREFIX = '/admin_media/'

Finally, there are a few LifeFlow specific values we need to add to our file:

LIFEFLOW_KEYWORDS = "Blog Will Larson Programming Life"
LIFEFLOW_DESCRIPTION = "Will Larson's blog about programming and other things."
LIFEFLOW_BLOG_NAME = "Irrational Exuberance"

The first two (LIFEFLOW_KEYWORDS and LIFEFLOW_DESCRIPTION) allow you to set the meta keywords, meta description for your blog.

LIFEFLOW_BLOG_NAME sets the name of your blog. This should be a string. The default value is "Unconfigured LifeFlow", and you probably don't want to call your blog that, although its kind of ironically catchy now that I think about it.

LIFEFLOW_AUTHOR_NAME is used to assign a destination to the 'About' link in the sidebar, and thus is rather important. We haven't created the first Author for the blog yet (we'll be doing that soon), but this allows you to specify the author's profile/biography that the About link goes to. If you don't set this value, then LifeFlow will automatically route the 'About' link to Author whose primary key is 1. (If you specify an invalid string (i.e. does not correspond to the name of an author), then it is going to send your users to an invalid page.)

LIFEFLOW_USE_PROJECTS is either True or False (True by default), and will correspondingly show or not show a link to the projects page in the links at the top of every page. (Projects are a lot like blog entries, but they don't have a date associated with them so they are /projects/lifeflow/ instead of something like /entry/2008/jan/03/lifeflow/ . They also have a few other things that distinguish them, but they are used akin to a simple portfolio.)

LIFEFLOW_GOOGLE_ANALYTICS_ID is used to specify a Google analytics ID for your site. If you don't want to use Google analytics, leaving this blank or setting it equal to None is completely acceptable.

The next two (LIFEFLOW_TEMPLATE_AUTHOR and LIFEFLOW_TEMPLATE_AUTHOR_URL) are used for overriding the author of the template you are using. If you fail to specify anything in then they will default to the creator of the default template (that would be me, I suppose). If, however, you explicitly specify either of them as None, then nothing will appear there.

The last three variables are probably the most interesting. All three of them expect a string in this format: "/media/lifeflow/mystyle.css" or "/media/myjs.js" or "/media/lifeflow/header.js", etc. Basically, they expect an absolute path to a file.

LIFEFLOW_CUSTOM_CSS expects a CSS file, which it will load after it has loaded all other LifeFlow CSS before hand. This is the easiest hook for customizing LifeFlow without mangling your SVN checkout. Almost every DIV has been named to facilitate this approach (although many of them don't have any CSS stylings associated with them in the default unmodified template).

LIFEFLOW_CUSTOM_JS_HEADER and LIFEFLOW_CUSTOM_JS_FOOTER are the same, except that they are expecting javascript files. The former will load the javascript file in the head of the file, and the later will load the javascript as the last thing before closing the body tag.

All three of the LIFEFLOW_CUSTOM_? classes are optional, and can be explicitly disabled with a value of None (but simply failing to specify them does the same).


Now we need to modify the file in our newly birthed project. Delete what is there already and paste in this:

from django.conf.urls.defaults import *
from django.conf import settings

urlpatterns = patterns(
    (r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT }),
    (r'^admin/', include('django.contrib.admin.urls')),
    (r'^', include('lifeflow.urls')),

This is my 'lazy as all hell' that I use for development. It uses the Django devel server (slow, awful for production sites, you know the drill) to serve static media, and grabs the document_root from the file.

Go ahead and save

Getting the devel server running

Okay, now we just need to sync our models and the database:

python syncdb

and then run the devel server:

python runserver

and we have LifeFlow running, although we need to make a few quick changes in the Django admin before we are done.

A Brief Tryst with the Django Admin

So fire up a browser and navigate to

Change one is to modify the site in the Sites application. You'll want the site with the primary key specified in your (by default this is 1) to specify your actual site. For example I have '' for both the domain name and display name. This domain name is used by the feed and syndication framework (which LifeFlow uses heavily), and also by the social submission links found at the end of each blog entry.

Then you'll want to create is an Author. If you specified a name for LIFEFLOW_AUTHOR_NAME, then be sure the name for your Author matches.

Next you want to create at least one Flow. The title shows up on each page, so make it something you like. The slug is used in the url, so you could make it shorter if you like.

Then you want to create at least one project if you set LIFEFLOW_USE_PROJECTS to True. If you don't create a project, then the Projects link at the top of your pages will direct you to a 404 error until you create a project later.

(You don't want to do this now, probably, but you may notice the 'Sites to Notify' entry in the Django Admin. That allows you to ping sites like Ping-O-Matic when you update your entries. Personally I only use Ping-O-Matic, but LifeFlow is about flexibility, so you can define arbitrary ones. The settings for Ping-O-Matic are pretty easy. Set the title as anything, the url to ping as '', and then blog title and blog url as the title and url of your blog (for example 'Irrational Exuberance' and '').)

Where to go from here

Soon I'll post an entry on deploying LifeFlow for production, but until then there are still a lot of ways for you to get to know LifeFlow for yourself. First, the project is relatively young and is still missing some features (for example, I don't really care for tracebacks, so they haven't been implemented yet, but if you implemented them, I'd be glad to push those changes to the SVN).

If that isn't your cup of tea, you can look into using the LIFEFLOW_CUSTOM_CSS setting in to load custom CSS files to personalize the look of your blog. (I hope to put up a quick post on customizing blog appearances via this method in the near future.)

Otherwise, I'd love to get more feedback about LifeFlow. What features do you feel it is missing? What are your complaints? Are you having trouble getting things set up? Let me know and I'll do my best to help!