I spent most of today trying to integrate AxKit with Template::Toolkit.
Unfortunately there isn’t really a lot of information on this available that I could find. I think most people see them as either/or approaches, rather than complementary. There is a mailing list for the two combined, but it’s fairly quiet – and seems to be more interested in using TT as a replacement for “XSLT”. I wanted to come at it from the other end – use TT to generate the “XML”, and then apply the XSLT to that XML using AxKit.
So, I decided to just blunder into it all, and see if I could make it work. It really didn’t seem like it should be that difficult.
My first attempt was to merely chain the two together:
<Location ...>
PerlHandler MDB::Site->handler AxKit
</Location>
Surprisingly, everything worked first time. I had TT output a calculated page, containing <?xml-stylesheet href=”/xslt/test.xsl” type=”text/xsl”?>, and AxKit happily used this to transform the page into a lovely “HTML” rendition. Or so I thought, until I tried it in IE and it fell over. After a lot of head-scratching I realised that actually AxKit wasn’t even getting near my output, and that Mozilla was applying the transformation client-side! IE was attempting to do the same, but failing.
After some more digging I realised that FireCore was set up to return DONE if it generated output, which would stop Apache even trying to fall through to the AxKit Handler. The server merrily sent out XML and my browser merrily transformed it. And whilst this would be perfect in a few years time, it’s not much use now, when most browsers can’t be relied on to do this properly. I wanted to do it server side.
So I changed FireCore to return OK instead of DONE, falling through to AxKit when it was done. But, when you chain together two PerlHandler calls, Apache will just call each as if it was two separate requests – not in sequence. So, whilst FireCore generated the XML from TT just fine, AxKit died horribly complaining that the XML file didn’t exist, outputting a bizarrely hybrid XML/200 error page!
I couldn’t find anything obvious in the Apache or the AxKit docs, and a quick google search didn’t reveal anything either, so I hopped onto the #axkit channel on IRC, and asked there. But everyone must have been at lunch or something, as there was complete silence.
After a little more digging around I discovered that AxKit allowed you to set up your own Provider class for when your source wouldn’t just be on disk. I was slightly perturbed by the “don’t even consider doing this without asking on the mailing list about it first” warnings everywhere, but it was my best approach for now. It actually wasn’t too hard. I just made my own MDB::AxKit::Provider class my Handler, and had it pretend to be the Apache handler and ask MDB::Site for the output for that URL. (FireCore hadn’t really ever expect to be queried in this way, so I had to tease apart a few things that were too tightly coupled, but it was a fairly trivial change, and a worthwhile one anyway)
But then, the nice people of the AxKit IRC channel all arrived back from wherever they had been, and pointed me to Apache::Filter, which lets you build up a chain of Apache Handlers, each of which operate in turn on the previous one’s output. Even though I’d gotten my own sublcass working, this seemed like it would be much cleaner in the long run. Apache::Filter only works with modules which have registered themselves with this, but AxKit has thoughtfully done so, and so all I needed to do, instead of the fancy subclassing, was to tell FireCore to register itself with Apache::Filter also, and then set up my Apache config:
PerlModule Apache::Filter
AxConfigProvider Apache::AxKit::Provider::Filter
No actual code needing written is always a good thing, in my books.
And, hey presto! Everything worked. Well, in Mozilla anyway. IE complained: “The XML page cannot be displayed”, as there was an unclosed meta tag.
I examined my XML. I examined my XSLT. I couldn’t find such tag. I looked at the page source in my browser, and there was indeed an <meta content=”text/html; charset=UTF-8″ http-equiv=”Content-Type”> tag. I examined my XML again. I examined my XSLT again. No sign of that anywhere.
The nice people on #axkit set my straight again. The W3C say that there should be such a tag, so AxKit helpfully inserts it if you haven’t set one up. No-one could work out why IE would care though. After a lot of head-scratching and playing with different things, I discovered that it worked in one IE window, and not in another! It seems IE had decided to cache the fact this file was XML much earlier when the transformation wasn’t happening at all, and was ignoring the fact that it was now HTML. Grrr.
I still didn’t like that my page wouldn’t validate as XHTML however, so it was suggested that I explicitly set an output method in my XSL: <xsl:output method="xml" media-type="text/html" />
And now, everything was wonderful. Apart from the HTML all being one big long line that you had to scroll horizontally forever to read if you wanted to view the source. Another slight modification later, and everything was even more wonderful: <xsl:output method="xml" media-type="text/html" indent="yes" />
They even showed me where to find all this information myself :)
So, now that Marc seems to have the search working again, and I know how to get everything working in an XML-ish fashion, we can back on track with getting the MusicDatabase back up an running again!
Tony MDB