For the past month or so, I’ve been busy working deep under the hood of my day job’s websites to pull together the worlds of lightweight content management (or, in other words, weblogs) and “enterprise” content management to create a new set of hybrid sites that one colleague jokingly christened “blortals”. They combine the interactive, personal approach of blogs with the content of our “big” websites . And they’re put together almost entirely with RSS and XML Style Language (XSL).
While XML-based client-side browser magic like AJAX is all the rage right now, sometimes simple server-side XML magic is better–especially when you’re dealing with aggregating content from multiple sources, and you want your page to load somewhat faster than continental drift. Besides, syndication formats aren’t just for clients anymore–as the number of applications and services that produce RSS and Atom feeds grow exponentially, the XML syndication formats can provide a quick and easy way to integrate related content from disparate sources. Call it “Loosely-coupled content management.”
For example, take a look at this blog here. It runs on a weblog server, but it could really run just about anywhere, because almost all of the content is rendered from XSL files that are pointed at RSS feeds from the weblog, and various news sites In the case of this site, the inbound news feeds are created by a query against our content management system for any stories where a certain company is in the field for “related company”.
In fact, getting the RSS feeds configured was half the battle. That’s because Adobe’s Macromedia Dreamweaver 8 not only includes a relatively designer-friendly mechanism for adding XSL transforms to dynamic pages, but the actual code components required to do server-side transformations for ColdFusion, ASP, ASP.NET and PHP.
The only real coding I had to do was in XPath language in the XSL files used to define the transforms, to control how many items from each RSS feed are displayed on the page. So, for example, to only get 4 items from a feed, I could just use:
<xsl:for-each select=”rss/channel/item[position() <= 4]“>
…
</xsl:for-each>
And, since in some cases I was able to re-use existing RSS feeds, I also had to strip out the advertisments that get inserted into those feeds.
Thanks to XPath, that’s not a problem, since I was able to insert conditional statements into the XSL. The ads in our RSS feeds all have “ADV” at the beginning of the title, so all I needed was a conditional statement that skipped items starting with ADV:
<xsl:if test=”not(starts-with(title, ‘ADV’))”>
…
</xsl:if>
Since I wanted to be able to reuse the XSL fragments I created to render other feeds, and wanted to be able to set the number of items rendered and the advertising test string at the time the RSS feed is rendered, I made those values into parameters. Here’s the XSL fragment I used to render the headlines from an RSS feed, linked to their stories:
<?xml version=”1.0″ encoding=”ISO-8859-1>
<!DOCTYPE xsl:stylesheet [
<!ENTITY nbsp " ">
<!ENTITY copy "©">
<!ENTITY reg "®">
<!ENTITY trade "™">
<!ENTITY mdash "—">
<!ENTITY ldquo "“">
<!ENTITY rdquo "”">
<!ENTITY pound "£">
<!ENTITY yen "¥">
<!ENTITY euro "€">
]>
<xsl:stylesheet version=”1.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” xmlns:wfw=”http://wellformedweb.org/CommentAPI/” xmlns:slash=”http://purl.org/rss/1.0/modules/slash/” xmlns:dc=”http://purl.org/dc/elements/1.1/“>
<xsl:output method=”html” encoding=”ISO-8859-1″/>
<xsl:param name=”ItemsPerPage” select=”4″ />
<xsl:param name=”advertcheck” select=”ADV” />
<xsl:template match=”/”>
<xsl:for-each select=”rss/channel/item[position() <= $ItemsPerPage]“>
<xsl:if test=”not(starts-with(title, $advertcheck))”>
<a xhref=’{link}’><h3><xsl:value-of select=”title”/></h3></a>
<p><xsl:value-of select=”description” disable-output-escaping=”yes”/></p>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
So, throw five or six transformations onto a dynamic web page, and before you know it you’ve got a portal. As they used to say in the Ronco ads, “It’s just that easy.”
And, since it’s XSL, that means that I can move the pages that render the feeds to any dynamic server platform I want with minimal recoding– to do a proof of concept, I took a site developed on a .NET-based Telligent blog server and ported it over to a Linux box running Apache and PHP in just under 4 minutes.