Xuff, px, bx, etc.

As of September 2021, more of this page is out-of-date. The input files are still the same .bx and .px, but now they are served by Django. See Real Django site for details.
As of January 2008, half of this page is out-of-date. The input files are the same, but the process for turning them into HTML is completely different. See Permalinks, Gravatars, and Django for details.

I create this site with custom tools. They’ve grown organically over time. The end result is idiosyncratic, and I wouldn’t recommend them to anyone, but they work for me.

Briefly, my requirements were:

I’ve used and grown these tools over the last four years. Things I like about them:

Things I don’t like about them:

Input files: px, bx, etc

My input files are all XML, in a handful of custom dialects. Pages start life as .px files; they look like this:

<?xml version='1.0' encoding='utf-8'?>
<page title='Xuff, px, bx, etc.'>

<what when='20051128T201000'>Created.</what>

<p>I create this site with custom tools.  They've grown organically over time.
The end result is idiosyncratic, and I wouldn't recommend them to anyone, but they
work for me.</p>

The dialect borrows liberally from XHTML, since that is a natural tagset to use when creating pages. For semantic constructs (such as the edit history of the page), I created my own tags. Each .px file eventually becomes a .html page on the site.

Blog entries are created in .bx files. Here’s a complete file:

<?xml version='1.0' encoding='utf-8'?>
<entry when='20050726T083044'>
<title>IPod Flea</title>
<via />
<a href='http://www.layersmagazine.com/features/feature_cs2/flea.htm'>iPod Flea</a>.

The .bx files are converted into .px files in various ways to become pages on the site.

Processing: Xuff

The conversion of files is done with XSLT transforms, run by a tool called Xuff. It’s an XML script engine. It knows how to perform tasks such as copying trees of files, collecting together a number of files into one XML file, running XSLT transforms over sets of files, splitting an XML file into a number of files, uploading files via FTP, and so on.

For example, here is a shortened snippet of all.xuff:

<treefile out='temp/all-blog.xml'>
    <files src='blog' include='*.bx' />

<xsl in='temp/all-blog.xml' style='blogmain.xslt' out='temp/blog/index.px' />

<xsl in='temp/all-blog.xml' style='feedentries.xslt' out='temp/blogfeed.xml' />
<xsl in='temp/blogfeed.xml' style='blogrss.xslt' out='html/blog/rss.xml'>
    <param name='brief' value='y'/>

    src='temp' include='*.px'
    dst='html' outext='.html'

This code:

Whenever I change a file comprising my site, I run a Xuff file to create the entire site as HTML files and upload the changed files to my host. There’s no attempt to generate only part of the site. This isn’t fast (it takes about two minutes on my computer), but it is simple.


If you’d like to take a look at the tools or try them out, you can download a snapshot of a subset of my site. To use it:

  1. Install some prerequisite Python modules: PyXML, Pyana, and SilverCity.
  2. Unpack the snapshot (nedsite.zip) somewhere (let’s call it c:\nedsite)
  3. Edit try.xuff to set the base param:
    <param name='base' value='file:///c:/nedsite/html/' />
  4. In the nedsite directory, execute:
    python xuff.py try.xuff
    This creates a local staging copy of the site.
  5. Launch a browser to c:\nedsite\html\index.html to see what you made.

If you use “python xuff.py tch.xuff” instead, it builds the files for the real site and uploads them to my host (except it won’t upload because it’s been neutered).

The snapshot zip file only includes a small subset of the blog entries (you’ll notice they all start with ‘a’), and some other large files are omitted, but the site should basically work.

See also


hello. Im regarding your page. Thankyou for the comments.

Add a comment:

Ignore this:
Leave this empty:
Name is required. Either email or web are required. Email won't be displayed and I won't spam you. Your web site won't be indexed by search engines.
Don't put anything here:
Leave this empty:
Comment text is Markdown.