EFX is a Content Management System (CMS) written in Tcl. I wrote it because I needed something to help my son's school maintain their events, news, newsletters pictures (a process in which they previously employed Frontpage). I took a look at Bricolage, and while it is really cool (plus it doesn't require you to use any kind of app server or apache plugin -- it produces plain old HTML pages), I found its use of Mason cumbersome and I wasn't ready to brush up on my Perl. Plus, its a really big system that is difficult to install and master. (My target was a fairly moderate site of about 30-40 pages plus 50 or so pictures.) I am still working on the school website (and EFX), but I found EFX already quite useful. EFX (so far) consists of * EFX engine - A template engine based on ideas behind Zope Page Templates (which I had the pleasure of helping to define back in 2000) where markup in embedded in XML (XHTML) attributes. * Navmenu - A Navigational tool that helps you build hierarchical navigational menus and map out your site. * Story - A simple news content management tool that allows users to just put text files (with a title and date line) in a directory for inclusion into the website. * Calendar - An event management tool that presents a calendar UI interface to an events page. The EFX engine is about 450 lines of Tcl that uses TclXml to parse and operate on XML documents to produce XHTML pages. It is the most interesting part of the system. Here are just a few of the commands it exposes inside of XML element attributes: * efx:eval="command" - Evaluates command. Eats element and children. No output. * efx:eval_r="command" - Evaluates command. Replaces element with result of the command. * efx:subst="" - Substitutes commands/variables in children. Outputs current node and children. * efx:onlyIf="expression" - Evaluates expression (with ''expr''). If true, outputs element and children. If false, eat element and children. * efx:foreach="var|command" - Iterates var over result of command, processing children (which may contain additional efx commands) until var is {}. * efx:processFile="input_file args" - Process additional XML files. ''Commands'' can be any Tcl expression. All commands and variables are evaluated within a common Tcl namespace. Each XML file is treated as a closure. Variable bindings introduced in each page is in effect until that page is finished (then any old bindings are restored). You can use efx:processFile to nest closures. Okay, enough of that, how about an example? Here is a simple blog that I made in about 20 minutes using the EFX toolkit: http://www.maplefish.com/todd/blog I intend on improving the blog for doing RSS feeds and a few more features, but since it is a ''static'' site, no feedback/comment support is planned. The source XML that generated all of the blog pages:
$BLOG_NAME