Many, many moons ago (August 07 to be precise), I wrote a blog entry on metadata properties for created feeds when using the CFFEED tag. I mentioned how the docs only cover a few of the possible items and mentioned nothing about metadata for Atom feeds. I said I'd follow up with an Atom example never got around to it. A reader graciously reminded me of this so I took a look earlier this week. Here is what I found.

First, I want to thank Ben Garret for sharing some links to the Atom specs. That is what I used for my testing and it was a great help. Specifically, this link inside the Atom spec focused on the elements that cover an Atom feed as a whole: http://www.atomenabled.org//developers/syndication/atom-format-spec.php#atom.documents

Specifically, here are the items supported:

atomFeed =
element atom:feed {
atomCommonAttributes,
(atomAuthor*
& atomCategory*
& atomContributor*
& atomGenerator?
& atomIcon?
& atomId
& atomLink*
& atomLogo?
& atomRights?
& atomSubtitle?
& atomTitle
& atomUpdated
& extensionElement*),
atomEntry*
}

For each item, a * at the end signifies 1 or multiple values are allowed. This is important because ColdFusion's CFFEED tag will require you to use an array. Read the docs for a full explanation on the rest, but in general, it is a mix of 'must have' and 'must have, but just one.' In my testing, nothing at all was required. I was able to use a metadata struct of just:

<cfset p = {}> <cfset p.version = "atom_1.0">

Obviously this isn't very descriptive, so I went down the list picking and choose various items to pick. Many of the items use what is called an atomTextConstruct. Take the feed title value. Because it is an atomTextConstruct, it requires a simple structure to work for cffeed:

<cfset p.title = {}> <cfset p.title.type = "text"> <cfset p.title.value = "Atom Title">

The type can be text, html, or xhtml. Text seemed to be the simplest so it's what I went with. Looking at the spec then you can see that subtitle is of the same type, so I can also do:

<cfset p.subtitle = {}> <cfset p.subtitle.type = "text"> <cfset p.subtitle.value = "My Sub Title">

I then played with categories. Again, I read the spec for that item and saw that it contained keys for term, scheme and label. I also knew the feed could have multiple categories, so I went with an array of structs:

<cfset p.category = []> <cfset p.category[1] = {}> <cfset p.category[1].term = "Fun Stuff"> <cfset p.category[2] = {}> <cfset p.category[2].term = "Boring Stuff">

Both author and contributor shared a spec type of atomPersonConstruct, so once I figured how that worked, it was also pretty trivial:

<cfset p.author = []> <cfset p.author[1] = {}> <cfset p.author[1].name = "Bill Gates"> <cfset p.author[1].uri = "http://www.microsoft.com"> <cfset p.author[1].email = "billg@microsoft.com">

<cfset p.contributor = []> <cfset p.contributor[1] = {}> <cfset p.contributor[1].name = "Raymond Camden"> <cfset p.contributor[1].uri = "http://www.coldfusionjedi.com"> <cfset p.contributor[1].email = "ray@camdenfamily.com">

That's really it I guess. I played around with other items and had luck with some - but not others. The updated value worked fine:

<cfset p.updated = now()>

I had been worried that it wouldn't use the right time format for Atom, but cffeed took care of it. You could add other items such as rights, id, logo, by just chercking the spec as I did.

Anyway, hope this helps. Personally I think Atom is a bit too verbose to work with. I'd rather just stick with RSS 2 feeds.