Calling Django from Scons

A simple script to build pages with Django

Posted by 05/08/2006

I'm trying to use <a href="http://scons.org">Scons</a> for some things these days. These are some of the problems I ran into with trying to run Django templates from a scons file.

I started off just wanting to use the Django templating system outside of the Django framework. No database. Just the template engine.

After much gnashing of teeth I was able to call Django from a python script, but then I wanted to take it one step further and make a SCons file so I could 'build' a web site using an actual build tool.

What I came up with so far (this is far from perfect) was what follows. A few notes:

  • Notice the mysterious line from django.template import loader - I don't have a good explanation for why this is necessary. It makes it possible to use {%include%} and {%extends%} though
  • Django kept complaining about UTF until I did this str(source[0]).encode('utf-8') to the parameters. That may be a red herring though.

The SContruct file:

import os
os.environ["DJANGO_SETTINGS_MODULE"] = "settings"

from django.template import Template
from django.template import Context
from django.template import loader

# runs django
def django(target, source, env):
    """ runs a django template, given target and source and dict of values"""
    input_file = str(source[0]).encode('utf-8')
    output_file = str(target[0]).encode('utf-8')
    
    t = Template(open(input_file).read())

    c = Context(env['context'])

    outfile = file(output_file, 'w')
    outfile.write(t.render(c))
    outfile.close()
    return None
       
django = Builder(action = django)

env = Environment(BUILDERS = {'Django' : django})


# index
context = dict({"name": "Rob"})
index = env.Django(source = 'src/index.html', target ='build/index.html', context=context)
Alias("index", index)


# default target(s)
Default("index")

Then I needed the settings.py file. I found it impossible to set the TEMPLATE_LOADERS and TEMPLATE_DIRS properties in the SConstruct file - which would have been my preference. Also __file__ did not work, so I had to make a settings.py file:

DEBUG = True
TEMPLATE_DEBUG = DEBUG

from os import path
MODULE_HOME = path.dirname(path.abspath(__file__)) + "/src/"

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.load_template_source',
)


TEMPLATE_DIRS = (
    MODULE_HOME,
    # Put strings here, like "/home/html/django_templates".
    # Always use forward slashes, even on Windows.
)

Granted this is useless to most people, but sometimes you just want to be able to generate a static web site, and I think the Django template engine - particulary the template inheritance - is a good template engine.

Comments

Post a comment


Total: 0.08 Python: 0.07 DB: 0.02 Queries: 33