June 7, 2006 at 10:05PM How I’m going to publish feeds from now on
With my new weblog software (called Shibumi, if you’re interested) complete, I thought I’d explain how I’m going to be serving up my feeds from now on.
For a start, I’m switching over to Atom 1.0, but keeping the RSS 2.0 feed as a hidden fallback. If the client making the request says it can handle Atom, it’ll get it. If it doesn’t, it’ll get RSS 1.0. In addition, I’m going to start using the <content:encoded/> to serve post content rather than <description>, which I’m going to use for plaintext summaries. I fully expect this will break something.
Once I’m happy with how it’s working, I’m going to break it some more by adding code to utilise HTTP caching fully and use the Last-Modified and If-Modified-Since headers to serve up only the items required.
Updated: Meant to type RSS 1.0 rather than RSS 2.0. Also, here’s how I’m generating the RSS 1.0 feed:
<?xml version="1.0" encoding="utf-8"?>
<rdf:RDF
xmlns="http://purl.org/rss/1.0/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xml:lang="en-ie">
<cfoutput>
<channel rdf:about="#XmlFormat(REQUEST.serverPath)#feed/">
<title>#XmlFormat(REQUEST.weblog)#</title>
<link>#XmlFormat(REQUEST.serverPath)#</link>
<cfif IsDefined("REQUEST.subtitle")>
<description>#XmlFormat(REQUEST.subtitle)#</description>
</cfif>
<dc:date>#MakeW3CDate(entries.updated)#</dc:date>
<dc:identifier>#XmlFormat(REQUEST.tag)#</dc:identifier>
</cfoutput>
<!--- Why is this necessary?! --->
<items>
<rdf:Seq>
<cfoutput query="entries">
<rdf:li resource="#XmlFormat(MakePermalink(published, slug))#" />
</cfoutput>
</rdf:Seq>
</items>
</channel>
<cfoutput query="entries">
<item rdf:about="#XmlFormat(MakePermalink(published, slug))#">
<title>#XmlFormat(title)#</title>
<link>#XmlFormat(MakePermalink(published, slug))#</link>
<dc:identifier>#XmlFormat(REQUEST.tag)#/#XmlFormat(slug)#</dc:identifier>
<cfif summary neq "">
<description>#XmlFormat(summary)#</description>
</cfif>
<cfif body neq "">
<content:encoded><![CDATA[#Textuality(body, smiliePath, true, true)#]]></content:encoded>
</cfif>
<dc:date>#MakeW3CDate(entries.published)#</dc:date>
<dc:creator>#XmlFormat(name)#</dc:creator>
<dc:rights>Copyright © #XmlFormat(name)#, #Year(published)#</dc:rights>
<cfif link_url neq "">
<dc:relation>#XmlFormat(link_url)#</dc:relation>
</cfif>
<cfif via_url neq "">
<dc:source>#XmlFormat(via_url)#"</dc:source>
</cfif>
<!--- I know dc:subject isn't synonymous with category, but screw it... --->
<cfloop index="tag" list="#tags#" delimiters="`">
<dc:subject>#XmlFormat(tag)#</dc:subject>
</cfloop>
</item>
</cfoutput>
</rdf:RDF>
And here’s the code for generating Atom:
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-ie">
<cfoutput>
<title>#XmlFormat(REQUEST.weblog)#</title>
<cfif IsDefined("REQUEST.subtitle")>
<subtitle>#XmlFormat(REQUEST.subtitle)#</subtitle>
</cfif>
<link rel="self" type="application/atom+xml" href="#XmlFormat(REQUEST.serverPath)#feed/" />
<link rel="alternate" type="text/html" href="#XmlFormat(REQUEST.serverPath)#" />
<!--- The topmost one will always give the most recently changed one. --->
<updated>#MakeW3CDate(entries.updated)#</updated>
<id>#XmlFormat(REQUEST.tag)#</id>
<generator version="1.0">Shibumi</generator>
</cfoutput>
<cfoutput query="entries">
<entry>
<title>#XmlFormat(title)#</title>
<link rel="alternate" href="#MakePermalink()#"/>
<cfif link_url neq "">
<link rel="related" href="#XmlFormat(link_url)#"/>
</cfif>
<cfif via_url neq "">
<link rel="via" href="#XmlFormat(via_url)#"/>
</cfif>
<id>#XmlFormat(REQUEST.tag)#/#XmlFormat(slug)#</id>
<published>#MakeW3CDate(published)#</published>
<updated>#MakeW3CDate(updated)#</updated>
<cfif summary neq "">
<summary>#XmlFormat(summary)#</summary>
</cfif>
<cfif body neq "">
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
#Textuality(body, smiliePath, true, true)#
</div>
</content>
</cfif>
<author>
<name>#XmlFormat(name)#</name>
</author>
<rights>Copyright © #XmlFormat(name)#, #Year(published)#</rights>
<cfloop index="tag" list="#tags#" delimiters="`">
<category term="#XmlFormat(tag)#"/>
</cfloop>
</entry>
</cfoutput>
</feed>
I’m trying to do the right thing, but I’m cheating a bit with <dc:subject>.