If you don't know how to open doors, how do
you get into a building? At best you might end up breaking a window
instead. Later on you'll figure out that tricky opening-a-door
idea, but that window is still broken. This is necessarily what
happens when intermediate developers work on projects: they have
insufficient knowledge and experience to get the design right from
the start, so they make and correct many mistakes in their designs
as they evolve.
LifeFlow is my oldest Django application that is still in use,
and anyone who has spoken with me with me--or
looked at the repo--knows that it has grown into a bit of a
beast. Let's take a quick inventory of the different functionality
that LifeFlow has, some of its design decisions, and the roadmap
for taking LifeFlow from broken to beautiful.
Design Decisions (Broken Windows and Doors)
The firt thing to acknowledge, is that LifeFlow clearly has some
bad design decisions. Like the analogy I started this entry with,
there are broken windows here.
When I started LF, I was deliberately bullish on the
app versus project distinction, because I wanted LF to
be a one-step deployment. Unfortunately, deploying on Django
is still prohibitively complex for the WordPress crowd
(vaguely a programmer on WordPress was who I was originally
targetting, by which I mean myself).
This was both a mistake and a failure.
LifeFlow has a ridiculous amount of
flexibility, but a lot of it is misguided flexibility that
overrides best-practice with arbitrary.
Flexibility will always be core to LF, but some of the existing
mechanisms need to be scaled back.
There are many ways to reach the same article.
Different people want different things, especially
as we move across cultures, there are simply different
ways for organizing and locating content.
LifeFlow wants to provide a wide cross-section of ways
to label and organize.
Really, I think the one-step deployment idea is at the root
of all the large failing with LifeFlow, and that by rejecting
it, it should be possible to salvage something good here.
Features (Guided and Misguided)
A few helpful notes before we get started:
YAGNI: You Aren't Gonna Need It. (For functionality that seems
thoughtful/useful, but is really just bloat.)
AOBP: Arbitrary Over Best Practice. (For places where best practice
was replaced with arbitrary solutions with no clear benefit.)
Okay, and now on to the feature list and the cutting block:
Support for skins, which make it easy for users to inject their
own custom CSS and JS.
Will be removed. (AOBP.)
Support for mods, which can add arbitrary functionality to
LifeFlow. The example mod is for setting up
Will be removed. (YAGNI.)
Text filters which allows all comments and entries to be
passed through arbitrary filters for modification.
This functionality is used to render comments and articles,
and also allows a tremendous amount of flexibility. You could
trivially implement a swear-word filter for comments, turn
the first occurance of Django into a link in each article,
or do almost anything, really.
The LifeFlow Editor, which is a complete Ajaxy replacement
for managing LifeFlow deployments (similar to the Django admin,
but with a blogging-centric workflow).
There is a lot of functionality packed into the LFE. Previewing
article rendering, a 'draft' concept, which distinguish between
published and unpublished articles, and much more.
Simple content management system for files.
Several custom markdown enhancements, including dynamic blog context,
as well as a custom syntax highlighting mechanism, and a syntax for
injecting ReStructed Text, Textile and raw markup into Markdown.
This stuff adds huge value for me, especially the dynamic blog context,
which has a number of tricks (the most helpful is that it automagically
allows including named files/images across articles once you have uploaded
Breaks the 'blog' into multiple flows, which are meta-tags for
content. The idea is to host multiple blogs each with their distinct
content and topic within one LF deployment, while allowing complete
cross-polination of the content (share tags, share archives,
are intermingled on front page, etc).
Projects which are non-date based data.
This is functionality that I really want, but I really
dislike my current implementation as well.
Its own implementation of threaded comments with spam
fighting reverse-captchas. (My comments are completely
open, and I get no comment spam. I'd hardly argue that
my implementation is superior to others, but merely
that it is sufficiently different and the number of
LF users small enough that spammers haven't yet figured it
Article series are a first-order citizen, which allows
some really useful organizational tweaks. I think this is
a really helpful feature, and it saves me a ton of time
compared to what I needed to do in WordPress.
Archive view for entries based on generic date views.
Sitemaps integrated into app.
Ten distinct types of rss feeds (all, author, flow, tag, series, translations, proejcts, comment, comments for entry, language).
Multiple author support, where each article can have
0+ authors associated with it.
Can notify an arbitrary list of sites when an entry is published.
BlogRoll for linking to other authors.
Changes (Stop, Innovate and Fix'in)
Looking at LF's goals and reality, here are the changes I
am planning to make:
Reset the 'backwards compatibility' guarantee.
Break LifeFlow into multiple applications.
LifeFlow-Core will contain core reusable code.
All other LifeFlow apps will be dependent on LF-Core.
LifeFlow-Blog will contain blog specific code.
LifeFlow-Projects will take over responsibility for displaying
LifeFlow-API which will expose a RESTFUL api that can be used
for managing LifeFlow content.
LifeFlow-Editor which is a complete Django-Admin replacement
for LifeFlow. (Implement on top of LF-API.)
Reorganize up the repository to reflect best-practices of directory
design for Django projects.
More tests, better tests.
Improve archive dramatically, which will require jettisoning
the date-based generic views and rolling something custom.
Better translation integration and support.
(I don't want translations to be included directly in the primary
feeds or browsing pages, but I do want to keep the translation
Rework a number of the models:
Move the SiteToNotify concept to a settings.py setting,
instead of having it as a model.
Consolidate the Draft and Translation models into the
I am going to begin this work in a new branch right this second.
We'll see where it takes us.