Note: Assuming your browser supports it, this list will not be printed out. Hide navigation

Writing An Atom Feed

Sunday 23rd October 2005

Introduction

To those of you wondering what Atom is, it is essentially an alternative to RSS. Hang on, you might say, then why should I bother learning Atom? Personally, I prefer using Atom over RSS since it is controlled by a standards body, whereas RSS... isn't. Unfortunately, RSS still has greater compatibility than Atom, hence the two feeds available on this site.

In particular, this article is looking at Atom 1.0, which is the latest version of Atom. Fortunately, Atom's history is rather simpler than that of RSS, with just an uncomplicated line of Atom 0.3 and Atom 1.0.

Largely because this page needs a bit more padding out, here's a sample feed:

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

<title>Example Feed</title>
<updated>2005-10-22T21:05:58Z</updated>
<id>tag:http://www.example.com,2005:1</id>

<entry>
<title>Atom-Powered Robots Run Amok</title>
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
<updated>2003-12-13T18:30:02Z</updated>
</entry>

</feed>

Writing the Basic Feed

A feed is generally made up of the feed itself, and the entries inside the channel. Before that, we need to define the file as an Atom 1.0 file. We do that using these two lines of code right at the beginning of the document:

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

You should also save the file with the extension .xml. If you are using PHP to dynamically generate the feed, you need to make sure the feed is sent as XML. To do this, add this line right at the beginning:

<?php header('Content-type: text/xml');?>

Next, we need a unique ID for the feed. The easiest way to create a unique ID is to use your website address. In case you no longer own the website in the future, you should also whack on the year. The format I use is this:

<id>tag:example.com/beans/,2005:1</id>

The two other required elements are the title and the time the feed was last updated. Both are fairly self explanatory, e.g.

<title type="text">Beans on example.com</title>
<updated>2005-10-22T21:20:45Z</updated>

Note that the title should be escaped, e.g. an ampersand should be written &amp;. By adding the appropriate attribute, you can also use (X)HTML markup for the title, but I feel that it is better to keep the feed simple, and not overburden it with details such as formatting. If you really must use HTML formatting, the easiest way is to use XHTML, otherwise each tag must be escaped. For example:

<title type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
Beans on <b>example.com</b>
</div>
</title>

The attribute type, and its possible values text, html and xhtml, also apply to subtitle, summary, content and rights elements.

The date/time should be in the format: YYYY-MM-DDTHH-MM-DDtimezoneoffset, replacing timezoneoffset with either the timezone offset from GMT, or a Z if there is no offset. Possible examples are:

<updated>2005-10-22T21:20:45Z</updated>
<updated>2005-10-22T21:20:45+01:00</updated>

Note that the time that the feed was updated doesn't have to take account of the smallest changes.

There are a number of other elements that you can enter. There must be an author element unless every single entry has an author element. You can add as many author entries as you like. The format is:

<author>
<name>Bob Jones</name>
<email>bobjones@example.com</email>
<uri>http://example.com/~bobjones</uri>
</author>

You should include the name - the email address and URI are optional. In a similar way, you can add as many contributors as you like, e.g.

<contributor>
<name>Betty Jones</name>
<email>bettyjones@example.com</email>
<uri>http://example.com/~bettyjones</uri>
</contributor>

<contributor>
<name>Brian Jones</name>
</contributor>

Another element that you should have is a link back to the feed itself. It should read something along the lines of:

<link rel="self" type="application/atom+xml" href="http://example.com/beans/atom.xml"/>

Obviously, the href attribute should be changed accordingly. There are a few other link tags that you can include. The main other one is called alternate - this links to another source on the internet that provides the same information e.g. the front page of the website. The format is the same:

<link rel="alternate" type="application/atom+xml" href="http://example.com/beans/"/>

As you can see on this feed, the link goes to the front page.

Finally, the last two elements I'll be covering are the subtitle and rights. The subtitle is simply a short spiel about the feed, while rights covers the copyrights of the feed. For example:

<subtitle type="text">The latest news on beans.</subtitle>
<rights type="text">All content on this website is copyright (C) 2005, example.com/beans</rights>

Much of what was said about titles applies here. To repeat almost verbatim: Note that the subtitle and rights should be escaped, e.g. an ampersand should be written &amp;. A copyright symbol can added by using &#169;. By adding the appropriate attribute, you can also use (X)HTML markup for the subtitle or rights, but I feel that it is better to keep the feed simple, and not overburden it with details such as formatting. If you really must use extra formatting, the easiest way is to use XHTML, otherwise each tag must be escaped. For example:

<subtitle type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
The latest news on <b>beans</b>.
</div>
</title>

So for the basic feed, you should now be able to make something similar to this:

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

<id>tag:example.com/beans/,2005:1</id>
<title type="text">Beans on example.com</title>
<subtitle type="text">The latest news on beans.</subtitle>
<rights type="text">All content on this website is copyright (C) 2005, example.com/beans</rights>
<updated>2005-10-22T21:20:45Z</updated>

<author>
<name>Bob Jones</name>
<email>bobjones@example.com</email>
<uri>http://example.com/~bobjones</uri>
</author>

<contributor>
<name>Betty Jones</name>
<email>bettyjones@example.com</email>
<uri>http://example.com/~bettyjones</uri>
</contributor>

<contributor>
<name>Brian Jones</name>
</contributor>

<link rel="self" type="application/atom+xml" href="http://example.com/beans/atom.xml"/>
<link rel="alternate" type="application/atom+xml" href="http://example.com/beans/"/>

Writing Each Entry

Next, we need to create the entries that make up the bulk of the feed. We start the entry with:

<entry>

Each entry must have a unique ID. The easiest way to do this for each entry is to take the web address; remove everything before the domain name; insert a comma after the domain name, followed by the year, day and month in the format YYYY-DD-MM that the article was published, then a colon. Finally, add tag: at the beginning. The result might be:

<id>tag:example.com,2005-10-22:beans/newrecord.html</id>

Be sure to convert any hashes (#) into forward slashes (/).

Next, we need a title and the last time the entry was updated, e.g.

<title>New Bean Eating Record</title>
<updated>2005-10-22T21:20:45Z</updated>

To essentially copy what I've written before: Note that the title should be escaped, e.g. an ampersand should be written &amp;. By adding the appropriate attribute, you can also use (X)HTML markup for the title, but I feel that it is better to keep the feed simple, and not overburden it with details such as formatting. If you really must use HTML formatting, the easiest way is to use XHTML, otherwise each tag must be escaped. For example:

<title type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
New <b>Bean Eating</b> Record
</div>
</title>

The date/time should be in the format: YYYY-MM-DDTHH-MM-DDtimezoneoffset, replacing timezoneoffset with either the timezone offset from GMT, or a Z if there is no offset. Possible examples are:

<updated>2005-10-22T21:20:45Z</updated>
<updated>2005-10-22T21:20:45+01:00</updated>

There are a number of other elements that you can enter. There must be an author element for every single entry unless the feed already has an author. You can add as many author entries as you like. The format is:

<author>
<name>Bob Jones</name>
<email>bobjones@example.com</email>
<uri>http://example.com/~bobjones</uri>
</author>

You should include the name - the email address and URI are optional. As before, you can also add some contributors in the entry, e.g.

<contributor>
<name>Betty Jones</name>
<email>bettyjones@example.com</email>
<uri>http://example.com/~bettyjones</uri>
</contributor>

<contributor>
<name>Brian Jones</name>
</contributor>

A summary or a content element should also be present - if not one, then the other. Again, these can both be written as text or XHTML, so I won't repeat what I've already said - I'm sure you can glance up the page to the title element! The content element should contain the entire story, whereas the summary is, as the name suggests, a short summary. You could have:

<summary>A man has broken the bean eating record by eating over 20,000 baked beans in under five minutes.</summary>

An alternative might be:

<content>A man has broken the bean eating record by eating over 20,000 baked beans in under five minutes. Hasn't he done well! Here is an interview from the man himself: blah blah blah etc. etc. etc.</content>

The last element that you should really include is another link element. This should point to the web page that contains the full story, especially if there is no content tag. The format is the same as before:

<link rel="alternate" href="http://www.example.com/beans/newrecord.html"/>

Finally finish off the entry with </entry>.

That should leave you with something along the lines of:

<entry>
<id>tag:example.com,2005-10-22:beans/newrecord.html</id>
<title>New Bean Eating Record</title>
<summary>A man has broken the bean eating record by eating over 20,000 baked beans in under five minutes.</summary>
<updated>2005-10-22T21:20:45Z</updated>
<link rel="alternate" href="http://www.example.com/beans/newrecord.html"/>

<author>
<name>Bob Jones</name>
<email>bobjones@example.com</email>
<uri>http://example.com/~bobjones</uri>
</author>
</entry>

Each entry can be added in the same way.

Finishing Touches

We are nearly there now! Firstly, we need to close the feed. We do this simply by adding this at the end of the XML file:

</feed>

Note that for each part of the feed, I haven't listed all the possible elements - you can find a fuller list using the Atom specification.

Now we need to add the feed to the website. We can do this in two ways. The first is to embed it in the pages of the websites. In the head of your pages, add this line:

<link rel="alternate" type="application/atom+xml" title="The Title Of Your Feed" href="atom.xml" />

Obviously, the title attibute should be the title of the feed, while the href attribute should point to the feed itself. This feed allows programs such as Opera and Mozilla Firefox to find the feeds. We can also add the feed as a button. First of all, you will need to find an appropiate button for your web page. You should be able to find a multitude of appropriate icons using the image search on Google. When you do use an image, make sure that you upload to your own webspace, and that it is not copyrighted. Common ones to use are the orange buttons with XML and Atom written on them, although, for the sake of continuity, this site has a different button.

Next, put the button on your page, and create a link to the Atom file. The (X)HTML code might look like this:

<a href="rss.xml"><img src="images/atom.png" alt="Atom 1.0 Feed" title="Atom Feed" height="15" width="80" /></a>

If you're using HTML, rather than XHTML, you won't need the forward slash at the end of the <img> tag. The various attributes, especially the link, image source and dimensions, will obviously need changing to the correct values.

And that should be it! Users of your site should now be able to find and view and your feed. If the feed doesn't work, make sure you have all the right tags, with correct spelling and cases (as in upper and lower cases), and that each tag is closed correctly.

Useful Links