Hacking StaticGenerator to work with Ellington .91

Why use StaticGenerator with Ellington?
StaticGenerator is a very useful python class for Django (version 0.96). It pretty much allows you to write static files for dynamic content. Static files, simply put, means faster performance.

However, serving dynamic content allows for greater flexibility. Get the very latest data for this web-page. That's GREAT! But pulling dynamic content constantly can drain the overall efficiency of your server(s).

When your dynamic content hasn't changed, why not create a static file of it to serve out to your users?

So what's the problem?
I'm not sure how useful this post will be... How many Ellington 0.91 developers can there be? The version of Ellington that we're using is based off of the Django 0.91 build. And well -- StaticGenerator is based off of Django 0.96. Uh-oh! That's a problem because there are quite a few changes between Django 0.91 and 0.96.

In order to get StaticGenerator working, you'll have to hack it a little bit.

Download the files first
Get the tar.gz file and extract the files. Copy or move the staticgenerator folder (with the __init__.py and the middleware.py files) to your ellington folder.

Hacking away
First modify the middleware.py file

change: from staticgenerator import StaticGenerator
to: from ellington.staticgenerator import StaticGenerator
Then modify the __init__.py file. At the very beginning, replace to imports:
import os
from django.http import HttpRequest
from django.core.handlers.base import BaseHandler
from django.db.models.base import ModelBase
from django.db.models.manager import Manager
from django.db.models import Model
from django.db.models.query import QuerySet
from django.utils.functional import Promise
from django.conf import settings

import os
from django.utils.httpwrappers import HttpRequest
from django.core.handlers.base import BaseHandler
from django.core.meta import ModelBase
from django.core.meta import Model
from django.utils.functional import Promise
from django.conf import settings

Basically, we're fixing the paths of a few imports in addition to chopping out the QuerySet and Manager classes. I don't believe they exist yet in 0.91.

Then find the extract_resources method.

# If it's a Manager, we get the QuerySet
if isinstance(resource, Manager):
resource = resource.all()

# Append all paths from obj.get_absolute_url() to list
if isinstance(resource, QuerySet):
extracted += [obj.get_absolute_url() for obj in resource]

try: resource = resource.get_list()
except: pass
try: extracted += [obj.get_absolute_url() for obj in resource]
except: pass
We're just removing code that doesn't quite work yet. Actually, I don't think we're ever going to use that method but these might be the steps you would take to get that working.

Removing the Static files on change
With Ellington 0.91, we want the static files to be removed whenever a story has been changed or a comment is added to it. Btw, when the static file doesn't exist we serve out the dynamic content (read up that bit about nginx on the StaticGenerator site). To do this you'll have to modify or add the _post_save method in the models you want to do this.

For example, with Ellington we want a Story to wipe out it's static version whenever it's saved. You can throw this tidbit of code into the _post_save method of the Story class.
from ellington.staticgenerator import quick_delete
except: pass
The rest of the Setup process
If you follow the StaticGenerator website, you need to add a few things to your settings.py file as well as setting up apache/nginx.

In the MIDDLEWARE_CLASSES tuple you can add
Then somewhere in the settings.py file you can also add:
SERVER_NAME = 'myservername'
WEB_ROOT = '/path/to/static_files'
In this example, we're only generating static Stories based on the url pattern of /stories/2009. Of course you can add any other url pattern. Also, make sure that the WEB_ROOT points to a directory that has the correct user/group permissions.

Updating static Index files
If you're statically generating static index pages, you'll need a way to wipe those out. It won't be removed after a story is saved unless you build you're own "CLEANER".

I think a much better way to do this is to add a cronjob, or a simple sh script that removes the static files every minute or so. In the script you could write:
cd /path/to/static_files # this really belongs in cron
find news -name "index.html" -exec rm -f {} \;
Here we scan through /path/to/static_files/news and any sub directories for "index.html" files and remove them.

You may also want to wipe our your "stories" or any other static files after a template change. That might look like:
find stories/2009 -name "index.html" -exec rm -f {} \;
Aren't there better ways to do this?
Yeah probably! :-p