I have been running my weblog on Movable Type for about a month now and I have
to say I am really impressed.  For a collection of scripts put together,
Movable Type is an impressive piece of software, both powerful and
intuitive.  I expected it to be a challenging installation, especially
since I am not running my blog on my home machine but at an ISP, but it turned
out to be remarkably painless.

Having said that, I have one big complaint:  no support for referrer logs. 
I couldn’t find any way to have quickly access to my referrer log anywhere in
the Movable Type distribution.  A quick Google query turned up several packages implemented in various
languages.  I tried a lot of them but I could never quite reach the result
I was looking for, so I decided to write my own.

My ISP conveniently stores the logs for my Web site every night in a
well-defined directory, following a standard naming notation for each day. 
I decided it would be easier to calculate my log referrer from these logs
instead of embedding scripting information in my main index file, since the
updates don’t really need to be more frequent than once a day.

Finally, I had to choose a language.  Since I opted for the static approach, I
am not limited to the languages that my ISP supports for CGI programming (PHP
and Perl).  The obvious choice was Ruby, which excels at this kind of
treatment with its native support for regular expressions, invocation of
external commands and offers an object-oriented language from the ground up
giving me extreme flexibility in my attempt to write a utility that will be easy
to extend for my future log parsing needs.

Since I was going to have to
generate HTML, I thought I would port a small Java class that I have been using
to generate XML in EJBGen called XMLStringBuffer.  The idea is simply to
not have to worry about indentation and closing the tags.  With this class,
generating XML is as simple as:


XMLStringBuffer xsb = new XMLStringBuffer();
xsb.push("person");
xsb.addRequired("last-name", m_lastName);
xsb.addOptional("first-name", m_firstName);
xsb.pop("person");

Note that I don't really need to specify the closing tag in the pop() call, but
it makes debugging easier since the XMLStringBuffer maintains an internal stack
of the tags and can therefore tell me right away if my push/pop get out of
synch.

It quickly occurred to me that I could make this class even fancier in Ruby
thanks to two features that are sadly absent from Java:  closures and method_missing (really dynamic typing).

The idea is to use closures to simulate indentation, and method_missing to make
the XML class allow invocations on any method.  If the said method
is unknown, it is simply turned into an XML tag.

Here is a piece of code that will make it all clearer:


xml = XML.new

xml.html {
  xml.head {
  }
  xml.body {
    xml.table {
      xml.tr {
        xml.td({ "valign"
=> "top"}, "Content1"){
        }
        xml.td {
          xml.append("Content2")
        }
      }
    }
  }
}

As you can see, each new
closure (pairs of { }) starts a new tag and will cause an indentation and the
proper tag to be closed when the block is exited.  Note also that every tag
can be passed a Hash that will be turned into attributes if found.  You can
also specify the content of the tag either inline or later in the closure with
the append() method.  The generated XML is as follows:


<html>
  <head>
  </head>
  <body>
    <table>
      <tr>
        <td valign="top">Content1</td>
        <td>
          Content2
        </td>
      </tr>
    </table>
  </body>
</html>

The XML class is about forty lines, including comments.

In a next entry, I will give more details about the logging utility itself.