Fixing What Ails LifeFlow
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.
One-step deployment.
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.
Flexibility everywhere.
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 StaticGenerator.
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 them).
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 out.)
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.
Tag cloud.
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 the projects.
- 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 functionality.)
- Rework a number of the models:
- Move the
SiteToNotify
concept to asettings.py
setting, instead of having it as a model. - Consolidate the
Draft
andTranslation
models into theEntry
model.
- Move the
I am going to begin this work in a new branch right this second. We'll see where it takes us.