As an example, look at the Syfy Portal newsfeed, which has the potential to contain over 3000 archived news stories (see Resources for a link). Virtually nobody wants their feed reader to download all of these messages, especially since many of them are several years old. To solve that problem, the Atom specification allows for the necessity to send only a portion of the available information.
In this case, the spec mandates the addition of several link elements that help lead the application along. Listing 1 shows an example.
Listing 1. The sample feed
<?xml version="1.0" encoding="us-ascii"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>SyFy Portal Headlines</title>
<link href="http://www.syfyportal.com"/>
<updated>2007-01-23T10:34:22Z</updated><id>http://www.syfyportal.com/a
tomfeed.php</id><subtitle>Your Premier Source For Science Fiction and
Fantasy News Since 1998</subtitle>
<link rel="alternate" type="text/html" hreflang="en"
href="http://www.syfyportal.com/"/>
<link rel="self" type="application/atom+xml"
href="http://www.syfyportal.com/atomFeed.php"/>
<link rel="first" href="http://www.syfyportal.com/atomFeed.php"/>
<link rel="next" href="http://www.syfyportal.com/atomFeed.php?page=2"/>
<link rel="last"
href="http://www.syfyportal.com/atomFeed.php?page=147"/>
<entry>
<id>http://www.syfyportal.com/news423172.html</id><title>'Heroes'
Holds Its Own Against '24'</title>
<link rel="alternate" type="text/html"
href="http://www.syfyportal.com/news423172.html"/>
<author><name>Michael
Hinman</name></author><updated>2007-01-23T10:03:08Z</updated>
<content>Who will win in the battle between NBC's "Heroes" and Fox's "24"? In
terms of overnight ratings, it's actually a virtual tie."Heroes" slid a bit in the
ratings to earn an 8.5 rating/12 share according ...</content>
</entry>
<entry>
...
|
In this case, you're looking at the first page, so this page specifies four pieces of information. The first is the URL for the actual page. The second is the URL for the first page in the series, which of course is the same as the current URL.
The next two, however, are where some of the power is, specifying the "next" and "last" pages respectively. This feed contains 20 items, so the first 20 items are on this page, items 21 through 40 are on page 2, and so on. All pages but the first also have an additional "previous" link (see Listing 2).
Listing 2. Page 2
...
<link rel="self" type="application/atom+xml"
href="http://www.syfyportal.com/atomFeed.php?page=2"/>
<link rel="first" href="http://www.syfyportal.com/atomFeed.php"/>
<link rel="previous"
href="http://www.syfyportal.com/atomFeed.php?page=1"/>
<link rel="next" href="http://www.syfyportal.com/atomFeed.php?page=3"/>
<link rel="last" href="http://www.syfyportal.com/atomFeed.php?page=147"/>
<entry>
...
|
Creating this functionality in PHP doesn't require any special skills or modules, just a methodical approach.
Consider this example, the PHP that generates the Atom feed for the Syfy Portal site. Generating the basic feed is straightforward (see Listing 3).
Listing 3: The basic feed
<?php
include("functions/engine.php");
header("Content-Type: text/xml");
$result = query("select * from content limit 20");
if (!result) {
echo "An error occured";
} else {
echo "<?xml version=\"1.0\" encoding=\"US-ASCII\"?>\n\n";
echo "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n\n";
echo "<title>SyFy Portal Headlines</title>\n";
echo "<link href=\"http://www.syfyportal.com\"/>\n";
echo "<updated>".date('Y-m-d\TH:i:s\Z')."</updated>";
echo "<id>http://www.syfyportal.com/atomfeed.php</id>";
echo "<subtitle>Your Premier Source For Science Fiction and
Fantasy News Since 1998</subtitle>\n";
echo "<link rel=\"alternate\" type=\"text/html\"
hreflang=\"en\" href=\"http://www.syfyportal.com/\"/>\n";
echo "<link rel=\"self\" type=\"application/atom+xml\"
href=\"http://www.syfyportal.com/atomFeed.php\"/>\n";
for ($i=0; $i < count($result); $i++){
$author = query("select * from authors where ".
"id='".$result[$i]['authorid']."'");
$item = $result[$i];
echo "<entry>\n";
echo "<id>http://www.syfyportal.com/news42".
$item['id'].".html</id>";
echo "<title>".
stripslashes(htmlspecialchars($item['headline']))."</title>\n";
echo "<link rel=\"alternate\" type=\"text/html\" ".
"href=\"http://www.syfyportal.com/news42".$item['id'].".html\"/>\n";
$hometext = strip_tags($item['body']);
if (strlen($hometext)>101) {
$desctext = htmlspecialchars(substr($hometext, 0,
strpos($hometext, ' ', 200)))." ...";
} else {
$desctext = htmlspecialchars($hometext);
}
echo
"<author><name>".$author['name']."</name></author>";
echo "<updated>".date('Y-m-d\TH:i:s\Z',
$result[$i]['added'])."</updated>";
echo "<content>".stripslashes($desctext)."</content>\n";
echo "</entry>\n\n";
}
echo "</feed>";
}
?>
|
Starting at the top, the site uses a number of internal routines, including one that wraps database transactions. Those are not the topic of this article, of course, but the important part is that the query() function returns an array of rows, each of which is itself represented as an array. The page loops through each of those items, creating an Atom feed.
To add paging capabilities, start by analyzing the available data (see Listing 4).
Listing 4. Adding paging
<?php
include("functions/engine.php");
header("Content-Type: text/xml");
$result = query("select * from content");
if (!result) {
echo "An error occured";
} else {
$numberOfItems = count($result);
$numberOfPages = intval($numberOfItems / 20);
if (isset($_GET['page'])){
$thisPage = $_GET['page'];
} else {
$thisPage = 1;
}
$offset = ($thisPage - 1) * 20;
echo "<?xml version=\"1.0\" encoding=\"US-ASCII\"?>\n\n";
echo "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n\n";
echo "<title>SyFy Portal Headlines</title>\n";
echo "<link href=\"http://www.syfyportal.com\"/>\n";
echo "<updated>".date('Y-m-d\TH:i:s\Z')."</updated>";
echo "<id>http://www.syfyportal.com/atomfeed.php</id>";
echo "<subtitle>Your Premier Source For Science Fiction and Fantasy News
Since 1998</subtitle>\n";
echo "<link rel=\"alternate\" type=\"text/html\"".
" hreflang=\"en\" href=\"http://www.syfyportal.com/\"/>\n";
echo "<link rel=\"self\" type=\"application/atom+xml\"".
" href=\"http://www.syfyportal.com/atomFeed.php\"/>\n";
echo "<link rel=\"first\"".
" href=\"http://www.syfyportal.com/atomFeed.php\" />\n";
if ($thisPage > 1){
echo "<link rel=\"previous\" ".
"href=\"http://www.syfyportal.com/atomFeed.php?page=".($thisPage-1).
"\" />\n";
}
if ($thisPage < $numberOfPages){
echo "<link rel=\"next\" ".
"href=\"http://www.syfyportal.com/atomFeed.php?page=".($thisPage+1).
"\" />\n";
}
echo "<link rel=\"last\" ".
"href=\"http://www.syfyportal.com/atomFeed.php?page=".$numberOfPages.
"\" />\n";
for ($i=$offset; ($i < ($offset + 20) and $i < count($result));
$i++){
$author = query("select * from authors where
id='".$result[$i]['authorid']."'");
$item = $result[$i];
echo "<entry>\n";
...
|
Previously, you let the SQL statement limit the number of records as a way to select a maximum of 20. In this case, you want to select all of the data that's available. From there, you can determine the maximum number of pages.
Next, determine what page you currently need to display and use that information to determine the offset, or number of records to skip.
Now it's time to add the actual links. The "first" and "last" link elements appear on all pages, but the "previous" and "next" links appear on all but the first and last pages, respectively.
Finally, adjust the loop so that it displays only the appropriate records, skipping those on previous pages and still displaying only 20. (In this case, 20 is an entirely arbitrary number.)
The result is an Atom feed that enables feedreaders or other applications to request only the records they want to see.
The Atom Publishing Protocol takes into account the fact that you don't always want to send all of your data to a requester, and provides a way to make this capability feasible. Use the first, next, previous, and last link elements to guide your users through your data in manageable chunks.
| Description | Name | Size | Download method |
|---|---|---|---|
| Atom paging samples | x-tipatom2-source.zip | 2KB | HTTP |
Information about download methods
Learn
-
Syfy Portal feed: See a live version of Atom in action.
-
An overview of the Atom 1.0 Syndication Format (James Snell, developerWorks, August 2005): See how this popular Web content syndication format stacks up.
-
Getting to know the Atom Publishing Protocol (James Snell, developerWorks, October - December 2006): Find out about the Atom API in this three-part series:
- Part 1: Create and edit Web resources with the Atom Publishing Protocol: Explore a high-level overview of the protocol and its basic operation and capabilities.
- Part 2: Put the Atom Publishing Protocol (APP) to work: Learn to use APP to interact with a number of real-world deployed applications.
- Part 3: Introducing the Apache Abdera project: Start to implement Atom-enabled apps using a new open-source project, called Abdera, currently under incubation at the Apache Software Foundation.
-
RSS and Atom in Action (Dave Johnson, Manning Publications, July 2006): If you prefer something more physical, take a look at this book about the blog technologies of news feed formats and publishing protocols and how to put these building blocks together. (Blogapps was put together for this book.)
-
Atom 1.0 specification: Read about this XML-based Web content and metadata syndication format.
-
Atom 1.0 compatible software: Visit the Atom Working Group's Wiki for a list of known Atom 1.0 feed consumers.
-
Use the Atom format for syndicating news and more (Uche Ogbuji, developerWorks, May 2004): Read more on this XML-based standard, format, and API for the interchange and cross-reference of Web metadata.
-
developerWorks XML zone: Learn all about XML at the developerWorks XML zone.
-
IBM XML certification: Find out how you can become an IBM-Certified Developer in XML and related technologies.
-
XML technical library: See the developerWorks XML zone for a wide range of technical articles and tips, tutorials, standards, and IBM Redbooks.
-
developerWorks technical events and webcasts: Stay current with technology in these sessions.
Get products and technologies
- The Blogapps server: Download the server in this collection of useful RSS and Atom utilities and examples.
Discuss
- Participate in the discussion forum.
-
XML zone discussion forums: Participate in any of several XML-centered forums.
Nicholas Chase has been involved in Web site development for companies such as Lucent Technologies, Sun Microsystems, Oracle, and the Tampa Bay Buccaneers. Nick has been a high school physics teacher, a low-level radioactive waste facility manager, an online science fiction magazine editor, a multimedia engineer, an Oracle instructor, and the Chief Technology Officer of an interactive communications company. He is the author of several books, including XML Primer Plus (Sams).
Comments (Undergoing maintenance)





