Index: /trunk/BookmarkApp.pm
===================================================================
--- /trunk/BookmarkApp.pm	(revision 8)
+++ /trunk/BookmarkApp.pm	(revision 9)
@@ -30,4 +30,5 @@
     $self->run_modes([qw{
         list
+        feed
         view
         edit
@@ -104,4 +105,37 @@
         );
     }
+}
+
+sub feed {
+    my $self = shift;
+    my $q = $self->query;
+
+    my $tag = $q->param('tag');
+
+    require XML::Atom::Feed;
+    require XML::Atom::Entry;
+    require XML::Atom::Link;
+
+    my $feed = XML::Atom::Feed->new;
+    $feed->title('Bookmarks');
+    $feed->id($base_uri . 'feed');
+
+    # construct a feed from the most recent 12 bookmarks
+    for my $bookmark ($bookmarks->get_resources({ tag => $tag, limit => 12 })) {
+        my $entry = XML::Atom::Entry->new;
+        $entry->id($bookmark->{bookmark_uri});
+        $entry->title($bookmark->{title});
+        my $link = XML::Atom::Link->new;
+        $link->href($bookmark->{uri});
+        $entry->add_link($link);
+        $entry->summary('Tags: ' . join(', ', @{ $bookmark->{tags} }));
+        $feed->add_entry($entry);
+    }
+
+    $self->header_props(
+        -type => 'application/atom+xml',
+        -charset => 'UTF-8',
+    );
+    return $feed->as_xml;
 }
 
Index: /trunk/Bookmarks.pm
===================================================================
--- /trunk/Bookmarks.pm	(revision 8)
+++ /trunk/Bookmarks.pm	(revision 9)
@@ -2,4 +2,5 @@
 
 use Class::Accessor 'antlers';
+use SQL::Interp qw{:all};
 use Bookmark;
 
@@ -36,12 +37,15 @@
     my $params = shift;
     my $tag = $params->{tag};
-    my $sth_resource;
-    if ($tag) {
-        $sth_resource = $self->dbh->prepare('select * from resources join tags on resources.uri = tags.uri join bookmarks on resources.uri = bookmarks.uri where tags.tag = ? order by ctime desc');
-        $sth_resource->execute($tag);
-    } else {
-        $sth_resource = $self->dbh->prepare('select * from resources join bookmarks on resources.uri = bookmarks.uri order by ctime desc');
-        $sth_resource->execute;
-    }
+    my $limit = $params->{limit};
+
+    my ($sql, @bind) = sql_interp(
+        'select * from resources join bookmarks on resources.uri = bookmarks.uri',
+        ($tag   ? ('join tags on resources.uri = tags.uri where tags.tag =', \$tag) : ''),
+        'order by ctime desc',
+        ($limit ? ('limit', \$limit) : ''),
+    );
+
+    my $sth_resource = $self->dbh->prepare($sql);
+    $sth_resource->execute(@bind);
 
     my $sth_tag = $self->dbh->prepare('select tag from tags where uri = ? order by tag');
Index: /trunk/index.cgi
===================================================================
--- /trunk/index.cgi	(revision 8)
+++ /trunk/index.cgi	(revision 9)
@@ -9,4 +9,6 @@
     table => [
         '[get]'              => { app => 'BookmarkApp', rm => 'list' },
+        'list[get]'          => { app => 'BookmarkApp', rm => 'list' },
+        'feed[get]'          => { app => 'BookmarkApp', rm => 'feed' },
         ':id/:field?[get]'   => { app => 'BookmarkApp', rm => 'view' },
         ':id?[post]'         => { app => 'BookmarkApp', rm => 'edit' },
