Implementing the Gateway
Most blogging platforms allow you to extract the list of posts as well as individual posts in a feed format (Atom or RSS). Blogger makes it extremely simple to get an Atom feed for a blog; you just have to use this URL:
Because the content is already encoded in XML (Atom uses XML structures) and will be transferred from the Blogger servers to the mobile gateway through an XMLHttpRequest object, using the XSLT on the output side to transform the already parsed XML DOM tree into target HTML seemed like a perfect match. The server-side script to read the Atom feed and transform it into WAP-compliant XHTML takes just a few lines:
Function ReadFeed(webSite,Cnt) Dim XFeed : Set XFeed = Server.CreateObject(DOMClass) SetXMLOptions XFeed If Not XFeed.Load("http://" & webSite & _ "/feeds/posts/default?max-results=" & CStr(Cnt)) Then Fail "Cannot get Atom feed from Blogger site " & webSite End If Set ReadFeed = XFeed End Function webSite = "ajaxandxml.blogspot.com" OutputXMLResponse ReadFeed(webSite,10),"firstPage.xsl"
Obviously, one of the reasons that the code is so short is the utility functions in my XML library, discussed in my article "Optimized Presentation of XML Content." This is a much simpler project, so the localized version of the OutputXMLResponse function is extremely short. The XSLT transformation function is a bit longer, however, as we need to fix XML-related encoding bugs in MSXML 3.0 in parallel with the HTML-related bugs.
The firstPage.xsl XSLT stylesheet is a bit more complex, primarily due to convoluted computations of URLs of individual blog posts within the restrictions of XSLT 1.0. (Unfortunately, Microsoft doesn’t plan to support XSLT 2.0 any time soon.) The only detail worth mentioning in the XSLT code is its header, where we need to define a number of namespaces: the XSL namespace, the Atom namespace (to be able to match the input elements), and the (default) XHTML namespace. Likewise, we need to use the xsl:output directive to insert the expected DOCTYPE declaration into the output XHTML, making it WAP 2.0 compliant.
<?xml version="1.0" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://www.w3.org/1999/xhtml" exclude-result-prefixes="atom" > <xsl:output method="xml" encoding="utf-8" doctype-public="-//WAPFORUM//DTD XHTML Mobile 1.0//EN" doctype-system="http://www.wapforum.org/DTD/xhtml-mobile10.dtd" />
The list of categories presented an interesting XSLT challenge. The categories cannot be downloaded as an Atom feed, but rather have to be extracted from the Atom post entries. As I wanted to retain the XSLT-focused approach, and XSLT 1.0 has no grouping functions, I ended up with a highly convoluted XSLT expression, which says approximately "Select categories from Atom entries such that no preceding Atom entry has an identical category," and results in a list of all categories in the Atom feed with removed duplicates.
<xsl:for-each select="//atom:entry//atom:category[not(@term = ../preceding-sibling::atom:entry/atom:category/@term)]/@term"> <xsl:sort order="ascending" />
The list is then sorted and displayed to the end user, as shown in Figure 3. The archive list and the lists of posts by category and month are very similar to the lists I’ve already discussed.
Figure 3 List of categories.
Readers who would like to adapt my solution to their needs are invited to download the source files from my web site. Please take into account that this is purely a proof-of-concept application that would need significant performance and caching improvements before being deployed in a large-scale production environment. I would also like to encourage you to send me improvements or new functionality (for example, displaying comment feeds).