I just did a massive check-in on mod_atom, and it’s now not just an Atom Store, it’s also a basic blog publisher. This fragment is about how it works, and includes a confession; I did one fairly awful thing along the way.
Still CoC · There’s still almost no configuration; just one directive, like so:
AtomPub /base/publication/URI /base/pub/dir "Pub Title" "Pub Author"
I keep thinking of places where configuration options would be useful, but then there’d need to be a configuration syntax and a place to put them, and it’s so easy to make a mistake there that you’ll have to live with for a long, long time. So I’m going to hold the line on more config stuff, for the moment.
Making HTML: What? ·
As of now, if you POST (or PUT) an Atom Entry to a mod_atom collection that
accepts them, it’ll generate an HTML version if the entry’s
content
element has a type
value of
text
or html
or xhtml
.
Whenever one of the HTML pages gets created or updated, mod_atom updates the publication’s “Front page” and a public-facing Atom feed for the publication.
Making HTML: How? · How, you might ask, does that HTML get created? Well, here’s the confession: I ended up inventing another HTML templating language. Because the Web doesn’t have enough. Here’s the current default template for the per-entry pages.
<html xmlns:m='http://www.mod-atom.net/ns'>
<head>
<title><m:title /></title>
<m:entry-stylesheet />
<m:entry-script />
<m:generator />
</head>
<body class='atom-body'>
<m:logo />
<h2><m:title /></h2>
<div class='atom-authors'>
<m:entry-author />
<m:contributors />
</div>
<div class='atom-content'>
<m:content />
</div>
<div class='atom-cats'>
<m:cats />
</div>
<div class='atom-rights'>
<m:rights />
</div>
<div class='atom-dates'>
<m:published />
<m:updated />
</div>
</body>
</html>
This template never gets applied at run-time, only at POST or PUT time.
There’s really quite a lot of scope for customization. Also, those
entry-stylesheet
and entry-script
template fields
generate something that look like:
<link href="/foo/bar/pub/e/entries/atom-entry.css" rel="stylesheet"></link>
<script src="/foo/bar/pub/e/entries/atom-entry.js" type="text/javascript"></script>
That, together with all those class attributes, ought to give you enough hooks to build as widget-packed and AJAXerrific a twenty-first century HTML page as anyone could want.
Sanitation · Earlier on, I had a bunch of HTML sanitation code that was applied to incoming POSTs and PUTs. I ripped it out again, so the Atom-store part of mod_atom screws with the incoming data as little as possible. But all that sanitation code does get applied to anything that comes out of the HTMLification process.
Does It Work? · Well, it passes the Ape test suite running on OS X and Debian. The HTML Entry and Front pages look OK, and while the public-facing feed has some problems (and is a first-rate conversation piece), it’s a start.
There are issues, of course, and if anyone starts using this, there’ll be lots more.
To Do ·
There are two big missing functional pieces. First off, it needs
to be easy to turn off all this HTML stuff so mod_atom is a pure Atom Store.
Second, it doesn’t support app:draft
, and if it got much out into
the wild in that state, Joe Cheng would send a poison dwarf from Redmond to
strangle my cats. And it’s easy enough to add, so I will.
Comment feed for ongoing:
From: Breton (Sep 16 2007, at 21:49)
If you don't mind me asking, why did you choose to invent a new templating language instead of using XSLT or some other existing language?
[link]
From: Joe Cheng [MSFT] (Sep 17 2007, at 00:18)
I don't mind if you don't support app:draft, so long as you at least refuse to PUT or POST entries with it set!
[link]
From: Asbjørn Ulsberg (Sep 17 2007, at 03:16)
I'll just repeat Brenton's comment and add that instead of defining a rigid template language, a better solution would be to define a rigid XML schema (as in RNG for instance) that XSLT could work upon.
XSLT provides all the functionality a template language needs and by defining how the XML model it is going to transform looks like (with RNG), it's fairly easy to do the transformations and "go wild" with the templates too.
And seeing that you already hav RFC-4287 support (it's mod_atom after all), why not just use that as your XML model that the XSLT will dance the transformation jiggy upon? Sounds pretty neat (and obvious) to me at least. :-)
[link]
From: roberthahn (Sep 17 2007, at 05:24)
I'm not the only one questioning this templating move. Why not repurpose something that's already well-understood (like SSI)?
[link]
From: Aristotle Pagaltzis (Sep 17 2007, at 06:32)
Asbjørn: completely agreed, but the defaults specified by Atom for various attributes and the structure of text constructs are all a bit of a pain to do in XSLT. (I’ve done the works for my weblog, so I know.)
So I would prefer if the Atom were either pre-normalised before the transform gets its hands on it, or if mod_atom provided a few XSLT extension functions for these purposes.
[link]
From: Tim Bray (Sep 17 2007, at 10:11)
All those who ask about other templating systems, notably XSLT: I share the concern with inventing a new one. Here's the problem: this thing gets compiled into HTTPD, and in my experience XSLT implementations are big and complicated and have nondeterministic performance, which I don't think is acceptable in the context of a potentially high volume Net-facing Web server.
So, if someone knows of a templating system that is simple, lightweight, the kind of thing you don't mind having in your Web server, and will give me programmatic access to the template processing, I would genuinely welcome the chance to adopt that and replace my own.
Note, however, that if you really want to use XSLT or some such, you can turn off mod_atom's HTML generation and run your own code on to take the stuff in the Atom store and transmogrify it into HTML (or anything, really). Sam Ruby's already sketched this in once, using Venus: http://intertwingly.net/blog/2007/06/28/Publishing-a-Blog-From-a-mod-atom-Store
[link]