changeset 5266:46c5e1ee8aaa

Added support for the Atom syndication format
author Robert Bachmann <rbach@rbach.priv.at>
date Thu, 30 Aug 2007 16:42:17 +0200
parents 980da86fc66a
children b962f82cfd61
files mercurial/hgweb/hgweb_mod.py mercurial/templater.py mercurial/util.py templates/atom/changelog.tmpl templates/atom/changelogentry.tmpl templates/atom/filelog.tmpl templates/atom/header.tmpl templates/atom/map templates/atom/tagentry.tmpl templates/atom/tags.tmpl templates/changelog.tmpl templates/filelog.tmpl templates/gitweb/changelog.tmpl templates/gitweb/changeset.tmpl templates/gitweb/error.tmpl templates/gitweb/fileannotate.tmpl templates/gitweb/filediff.tmpl templates/gitweb/filelog.tmpl templates/gitweb/filerevision.tmpl templates/gitweb/footer.tmpl templates/gitweb/index.tmpl templates/gitweb/manifest.tmpl templates/gitweb/map templates/gitweb/search.tmpl templates/gitweb/shortlog.tmpl templates/gitweb/summary.tmpl templates/gitweb/tags.tmpl templates/map templates/old/changelog.tmpl templates/old/filelog.tmpl templates/old/map templates/old/shortlog.tmpl templates/old/tags.tmpl templates/shortlog.tmpl templates/tags.tmpl
diffstat 35 files changed, 144 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/hgweb/hgweb_mod.py
+++ b/mercurial/hgweb/hgweb_mod.py
@@ -206,7 +206,7 @@ class hgweb(object):
                                           opts=diffopts), f, tn)
 
     def changelog(self, ctx, shortlog=False):
-        def changelist(**map):
+        def changelist(limit=0,**map):
             cl = self.repo.changelog
             l = [] # build a list in forward order for efficiency
             for i in xrange(start, end):
@@ -226,6 +226,9 @@ class hgweb(object):
                              "tags": self.nodetagsdict(n),
                              "branches": self.nodebranchdict(ctx)})
 
+            if limit > 0:
+                l = l[:limit]
+
             for e in l:
                 yield e
 
@@ -243,7 +246,9 @@ class hgweb(object):
         yield self.t(shortlog and 'shortlog' or 'changelog',
                      changenav=changenav,
                      node=hex(cl.tip()),
-                     rev=pos, changesets=count, entries=changelist,
+                     rev=pos, changesets=count,
+                     entries=lambda **x: changelist(limit=0,**x),
+                     latestentry=lambda **x: changelist(limit=1,**x),
                      archives=self.archivelist("tip"))
 
     def search(self, query):
@@ -344,7 +349,7 @@ class hgweb(object):
         pos = end - 1
         parity = paritygen(self.stripecount, offset=start-end)
 
-        def entries(**map):
+        def entries(limit=0, **map):
             l = []
 
             for i in xrange(start, end):
@@ -362,13 +367,17 @@ class hgweb(object):
                              "child": self.siblings(fctx.children()),
                              "desc": ctx.description()})
 
+            if limit > 0:
+                l = l[:limit]
+
             for e in l:
                 yield e
 
         nodefunc = lambda x: fctx.filectx(fileid=x)
         nav = revnavgen(pos, pagelen, count, nodefunc)
         yield self.t("filelog", file=f, node=hex(fctx.node()), nav=nav,
-                     entries=entries)
+                     entries=lambda **x: entries(limit=0, **x),
+                     latestentry=lambda **x: entries(limit=1, **x))
 
     def filerevision(self, fctx):
         f = fctx.path()
@@ -508,10 +517,14 @@ class hgweb(object):
         i.reverse()
         parity = paritygen(self.stripecount)
 
-        def entries(notip=False, **map):
+        def entries(notip=False,limit=0, **map):
+            count = 0
             for k, n in i:
                 if notip and k == "tip":
                     continue
+                if limit > 0 and count >= limit:
+                    continue
+                count = count + 1
                 yield {"parity": parity.next(),
                        "tag": k,
                        "date": self.repo.changectx(n).date(),
@@ -519,8 +532,9 @@ class hgweb(object):
 
         yield self.t("tags",
                      node=hex(self.repo.changelog.tip()),
-                     entries=lambda **x: entries(False, **x),
-                     entriesnotip=lambda **x: entries(True, **x))
+                     entries=lambda **x: entries(False,0, **x),
+                     entriesnotip=lambda **x: entries(True,0, **x),
+                     latestentry=lambda **x: entries(True,1, **x))
 
     def summary(self):
         i = self.repo.tagslist()
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -270,6 +270,7 @@ common_filters = {
     "permissions": permissions,
     "person": person,
     "rfc822date": lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S"),
+    "rfc3339date": lambda x: util.datestr(x, "%Y-%m-%dT%H:%M:%S", True, "%+03d:%02d"),
     "short": lambda x: x[:12],
     "shortdate": shortdate,
     "stringify": stringify,
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -1448,7 +1448,7 @@ def makedate():
         tz = time.timezone
     return time.mktime(lt), tz
 
-def datestr(date=None, format='%a %b %d %H:%M:%S %Y', timezone=True):
+def datestr(date=None, format='%a %b %d %H:%M:%S %Y', timezone=True, timezone_format=" %+03d%02d"):
     """represent a (unixtime, offset) tuple as a localized time.
     unixtime is seconds since the epoch, and offset is the time zone's
     number of seconds away from UTC. if timezone is false, do not
@@ -1456,7 +1456,7 @@ def datestr(date=None, format='%a %b %d 
     t, tz = date or makedate()
     s = time.strftime(format, time.gmtime(float(t) - tz))
     if timezone:
-        s += " %+03d%02d" % (-tz / 3600, ((-tz % 3600) / 60))
+        s += timezone_format % (-tz / 3600, ((-tz % 3600) / 60))
     return s
 
 def strdate(string, format, defaults):
new file mode 100644
--- /dev/null
+++ b/templates/atom/changelog.tmpl
@@ -0,0 +1,10 @@
+#header#
+ <!-- Changelog -->
+ <id>{urlbase}{url}</id>
+ <link rel="self" href="{urlbase}{url}atom-log"/>
+ <link rel="alternate" href="{urlbase}{url}"/>
+ <title>#repo|escape# Changelog</title>
+ #latestentry%feedupdated#
+
+#entries%changelogentry#
+</feed>
new file mode 100644
--- /dev/null
+++ b/templates/atom/changelogentry.tmpl
@@ -0,0 +1,16 @@
+ <entry>
+  <title>#desc|strip|firstline|strip|escape#</title>
+  <id>http://www.selenic.com/mercurial/#changeset-{node}</id>
+  <link href="{urlbase}{url}rev/{node}"/>
+  <author>
+   <name>#author|person|escape#</name>
+   <email>#author|email|obfuscate#</email>
+  </author>
+  <updated>#date|rfc3339date#</updated>
+  <published>#date|rfc3339date#</published>
+  <content type="xhtml">
+   <xhtml:div>
+    <xhtml:pre xml:space="preserve">#desc|escape#</xhtml:pre>
+   </xhtml:div>
+  </content>
+ </entry>
new file mode 100644
--- /dev/null
+++ b/templates/atom/filelog.tmpl
@@ -0,0 +1,8 @@
+#header#
+ <id>{urlbase}{url}atom-log/tip/{file|escape}</id>
+ <link rel="self" href="{urlbase}{url}atom-log/tip/{file|escape}"/>
+ <title>#repo|escape#: #file|escape# history</title>
+ #latestentry%feedupdated#
+
+#entries%changelogentry#
+</feed>
new file mode 100644
--- /dev/null
+++ b/templates/atom/header.tmpl
@@ -0,0 +1,4 @@
+Content-type: application/atom+xml; charset={encoding}
+
+<?xml version="1.0" encoding="{encoding}"?>
+<feed xmlns="http://www.w3.org/2005/Atom" xmlns:xhtml="http://www.w3.org/1999/xhtml">
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/templates/atom/map
@@ -0,0 +1,9 @@
+default = 'changelog'
+feedupdated = '<updated>#date|rfc3339date#</updated>'
+header = header.tmpl
+changelog = changelog.tmpl
+changelogentry = changelogentry.tmpl
+filelog = filelog.tmpl
+filelogentry = filelogentry.tmpl
+tags = tags.tmpl
+tagentry = tagentry.tmpl
new file mode 100644
--- /dev/null
+++ b/templates/atom/tagentry.tmpl
@@ -0,0 +1,8 @@
+ <entry>
+  <title>#tag|escape#</title>
+  <link rel="alternate" href="{urlbase}{url}rev/{node}"/>
+  <id>http://www.selenic.com/mercurial/#tag-{node}</id>
+  <updated>#date|rfc3339date#</updated>
+  <published>#date|rfc3339date#</published>
+  <content type="text">#tag|strip|escape#</content>
+ </entry>
new file mode 100644
--- /dev/null
+++ b/templates/atom/tags.tmpl
@@ -0,0 +1,11 @@
+#header#
+ <id>{urlbase}{url}</id>
+ <link rel="self" href="{urlbase}{url}atom-tags"/>
+ <link rel="alternate" href="{urlbase}{url}tags"/>
+ <title>#repo|escape#: tags</title>
+ <summary>#repo|escape# tag history</summary>
+ <author><name>Mercurial SCM</name></author>
+ #latestentry%feedupdated#
+
+#entriesnotip%tagentry#
+</feed>
--- a/templates/changelog.tmpl
+++ b/templates/changelog.tmpl
@@ -1,5 +1,7 @@
 #header#
 <title>#repo|escape#: changelog</title>
+<link rel="alternate" type="application/atom+xml"
+   href="#url#atom-log" title="Atom feed for #repo|escape#">
 <link rel="alternate" type="application/rss+xml"
    href="#url#rss-log" title="RSS feed for #repo|escape#">
 </head>
@@ -11,6 +13,7 @@
 <a href="#url#file/#node|short#{sessionvars%urlparameter}">manifest</a>
 #archives%archiveentry#
 <a type="application/rss+xml" href="#url#rss-log">rss</a>
+<a type="application/atom+xml" href="#url#atom-log" title="Atom feed for #repo|escape#">atom</a>
 </div>
 
 <h2>changelog for #repo|escape#</h2>
--- a/templates/filelog.tmpl
+++ b/templates/filelog.tmpl
@@ -1,5 +1,7 @@
 #header#
 <title>#repo|escape#: #file|escape# history</title>
+<link rel="alternate" type="application/atom+xml"
+   href="#url#atom-log/tip/#file|urlescape#" title="Atom feed for #repo|escape#:#file#">
 <link rel="alternate" type="application/rss+xml"
    href="#url#rss-log/tip/#file|urlescape#" title="RSS feed for #repo|escape#:#file#">
 </head>
@@ -13,6 +15,7 @@
 <a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">file</a>
 <a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">annotate</a>
 <a type="application/rss+xml" href="#url#rss-log/tip/#file|urlescape#">rss</a>
+<a type="application/atom+xml" href="#url#atom-log/tip/#file|urlescape#" title="Atom feed for #repo|escape#:#file#">atom</a>
 </div>
 
 <h2>#file|escape# revision history</h2>
--- a/templates/gitweb/changelog.tmpl
+++ b/templates/gitweb/changelog.tmpl
@@ -1,5 +1,7 @@
 #header#
 <title>#repo|escape#: Changelog</title>
+<link rel="alternate" type="application/atom+xml"
+   href="{url}atom-log" title="Atom feed for #repo|escape#">
 <link rel="alternate" type="application/rss+xml"
    href="{url}rss-log" title="RSS feed for #repo|escape#">
 </head>
--- a/templates/gitweb/changeset.tmpl
+++ b/templates/gitweb/changeset.tmpl
@@ -1,5 +1,7 @@
 #header#
 <title>{repo|escape}: changeset {rev}:{node|short}</title>
+<link rel="alternate" type="application/atom+xml"
+   href="{url}atom-log" title="Atom feed for #repo|escape#">
 <link rel="alternate" type="application/rss+xml"
    href="{url}rss-log" title="RSS feed for #repo|escape#">
 </head>
--- a/templates/gitweb/error.tmpl
+++ b/templates/gitweb/error.tmpl
@@ -1,5 +1,7 @@
 #header#
 <title>#repo|escape#: Error</title>
+<link rel="alternate" type="application/atom+xml"
+   href="{url}atom-log" title="Atom feed for #repo|escape#">
 <link rel="alternate" type="application/rss+xml"
    href="{url}rss-log" title="RSS feed for #repo|escape#">
 </head>
--- a/templates/gitweb/fileannotate.tmpl
+++ b/templates/gitweb/fileannotate.tmpl
@@ -1,5 +1,7 @@
 #header#
 <title>{repo|escape}: {file|escape}@{node|short} (annotated)</title>
+<link rel="alternate" type="application/atom+xml"
+   href="{url}atom-log" title="Atom feed for #repo|escape#">
 <link rel="alternate" type="application/rss+xml"
    href="{url}rss-log" title="RSS feed for #repo|escape#">
 </head>
--- a/templates/gitweb/filediff.tmpl
+++ b/templates/gitweb/filediff.tmpl
@@ -1,5 +1,7 @@
 {header}
 <title>{repo|escape}: diff {file|escape}</title>
+<link rel="alternate" type="application/atom+xml"
+   href="{url}atom-log" title="Atom feed for #repo|escape#">
 <link rel="alternate" type="application/rss+xml"
    href="{url}rss-log" title="RSS feed for {repo|escape}">
 </head>
--- a/templates/gitweb/filelog.tmpl
+++ b/templates/gitweb/filelog.tmpl
@@ -1,5 +1,7 @@
 #header#
 <title>#repo|escape#: File revisions</title>
+<link rel="alternate" type="application/atom+xml"
+   href="{url}atom-log" title="Atom feed for #repo|escape#">
 <link rel="alternate" type="application/rss+xml"
    href="{url}rss-log" title="RSS feed for #repo|escape#">
 </head>
--- a/templates/gitweb/filerevision.tmpl
+++ b/templates/gitweb/filerevision.tmpl
@@ -1,5 +1,7 @@
 #header#
 <title>{repo|escape}: {file|escape}@{node|short}</title>
+<link rel="alternate" type="application/atom+xml"
+   href="{url}atom-log" title="Atom feed for #repo|escape#">
 <link rel="alternate" type="application/rss+xml"
    href="{url}rss-log" title="RSS feed for #repo|escape#">
 </head>
--- a/templates/gitweb/footer.tmpl
+++ b/templates/gitweb/footer.tmpl
@@ -1,6 +1,7 @@
 <div class="page_footer">
 <div class="page_footer_text">#repo|escape#</div>
-<a class="rss_logo" href="#url#rss-log">RSS</a>
+<a class="rss_logo" href="#url#rss-log">RSS</a> 
+<a class="rss_logo" href="#url#atom-log">Atom</a>
 <br />
 #motd#
 </div>
--- a/templates/gitweb/index.tmpl
+++ b/templates/gitweb/index.tmpl
@@ -14,6 +14,7 @@
         <td><a href="?sort=#sort_contact#">Contact</a></td>
         <td><a href="?sort=#sort_lastchange#">Last change</a></td>
         <td>&nbsp;</td>
+        <td>&nbsp;</td>
     <tr>
     #entries%indexentry#
 </table>
--- a/templates/gitweb/manifest.tmpl
+++ b/templates/gitweb/manifest.tmpl
@@ -1,5 +1,7 @@
 #header#
 <title>#repo|escape#: Manifest</title>
+<link rel="alternate" type="application/atom+xml"
+   href="{url}atom-log" title="Atom feed for #repo|escape#">
 <link rel="alternate" type="application/rss+xml"
    href="{url}rss-log" title="RSS feed for #repo|escape#">
 </head>
--- a/templates/gitweb/map
+++ b/templates/gitweb/map
@@ -52,7 +52,7 @@ branchtag = '<span class="branchtag" tit
 shortlogentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><i>#author|person#</i></td><td><a class="list" href="{url}rev/#node|short#{sessionvars%urlparameter}"><b>#desc|strip|firstline|escape#</b> <span class="logtags">{branches%branchtag}{tags%tagtag}</span></a></td><td class="link" nowrap><a href="{url}rev/#node|short#{sessionvars%urlparameter}">changeset</a> | <a href="{url}file/#node|short#{sessionvars%urlparameter}">manifest</a></td></tr>'
 filelogentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><a class="list" href="{url}rev/#node|short#{sessionvars%urlparameter}"><b>#desc|strip|firstline|escape#</b></a></td><td class="link"><a href="{url}file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">file</a>&nbsp;|&nbsp;<a href="{url}diff/#node|short#/#file|urlescape#{sessionvars%urlparameter}">diff</a>&nbsp;|&nbsp;<a href="{url}annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">annotate</a> #rename%filelogrename#</td></tr>'
 archiveentry = ' | <a href="{url}archive/{node|short}{extension}">#type|escape#</a> '
-indexentry = '<tr class="parity#parity#"><td><a class="list" href="#url#{sessionvars%urlparameter}"><b>#name|escape#</b></a></td><td>#description#</td><td>#contact|obfuscate#</td><td class="age">#lastchange|age# ago</td><td class="indexlinks"><a class="rss_logo" href="#url#rss-log">RSS</a> #archives%archiveentry#</td></tr>'
+indexentry = '<tr class="parity#parity#"><td><a class="list" href="#url#{sessionvars%urlparameter}"><b>#name|escape#</b></a></td><td>#description#</td><td>#contact|obfuscate#</td><td class="age">#lastchange|age# ago</td><td class="indexlinks">#archives%archiveentry#</td><td><a class="rss_logo" href="#url#rss-log">RSS</a> <a class="rss_logo" href="#url#atom-log">Atom</a></td></tr>'
 index = index.tmpl
 urlparameter = '#separator##name#=#value|urlescape#'
 hiddenformentry = '<input type="hidden" name="#name#" value="#value|escape#" />'
--- a/templates/gitweb/search.tmpl
+++ b/templates/gitweb/search.tmpl
@@ -1,5 +1,7 @@
 #header#
 <title>#repo|escape#: Search</title>
+<link rel="alternate" type="application/atom+xml"
+   href="{url}atom-log" title="Atom feed for #repo|escape#">
 <link rel="alternate" type="application/rss+xml"
    href="{url}rss-log" title="RSS feed for #repo|escape#">
 </head>
--- a/templates/gitweb/shortlog.tmpl
+++ b/templates/gitweb/shortlog.tmpl
@@ -1,5 +1,7 @@
 #header#
 <title>#repo|escape#: Shortlog</title>
+<link rel="alternate" type="application/atom+xml"
+   href="{url}atom-log" title="Atom feed for #repo|escape#">
 <link rel="alternate" type="application/rss+xml"
    href="{url}rss-log" title="RSS feed for #repo|escape#">
 </head>
--- a/templates/gitweb/summary.tmpl
+++ b/templates/gitweb/summary.tmpl
@@ -1,5 +1,7 @@
 #header#
 <title>#repo|escape#: Summary</title>
+<link rel="alternate" type="application/atom+xml"
+   href="{url}atom-log" title="Atom feed for #repo|escape#">
 <link rel="alternate" type="application/rss+xml"
    href="{url}rss-log" title="RSS feed for #repo|escape#">
 </head>
--- a/templates/gitweb/tags.tmpl
+++ b/templates/gitweb/tags.tmpl
@@ -1,5 +1,7 @@
 #header#
 <title>#repo|escape#: Tags</title>
+<link rel="alternate" type="application/atom+xml"
+   href="{url}atom-log" title="Atom feed for #repo|escape#">
 <link rel="alternate" type="application/rss+xml"
    href="{url}rss-log" title="RSS feed for #repo|escape#">
 </head>
--- a/templates/map
+++ b/templates/map
@@ -47,7 +47,7 @@ filediffparent = '<tr><th class="parent"
 filelogparent = '<tr><th>parent #rev#:</th><td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
 filediffchild = '<tr><th class="child">child #rev#:</th><td class="child"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
 filelogchild = '<tr><th>child #rev#:</th><td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
-indexentry = '<tr class="parity#parity#"><td><a href="#url#{sessionvars%urlparameter}">#name|escape#</a></td><td>#description#</td><td>#contact|obfuscate#</td><td class="age">#lastchange|age# ago</td><td class="indexlinks"><a href="#url#rss-log">RSS</a> #archives%archiveentry#</td></tr>'
+indexentry = '<tr class="parity#parity#"><td><a href="#url#{sessionvars%urlparameter}">#name|escape#</a></td><td>#description#</td><td>#contact|obfuscate#</td><td class="age">#lastchange|age# ago</td><td class="indexlinks"><a href="#url#rss-log">RSS</a> <a href="#url#atom-log">Atom</a> #archives%archiveentry#</td></tr>'
 index = index.tmpl
 archiveentry = '<a href="#url#archive/#node|short##extension|urlescape#">#type|escape#</a> '
 notfound = notfound.tmpl
--- a/templates/old/changelog.tmpl
+++ b/templates/old/changelog.tmpl
@@ -1,5 +1,7 @@
 #header#
 <title>#repo|escape#: changelog</title>
+<link rel="alternate" type="application/atom+xml"
+   href="#url#atom-log" title="Atom feed for #repo|escape#">
 <link rel="alternate" type="application/rss+xml"
    href="?cmd=changelog;style=rss" title="RSS feed for #repo|escape#">
 </head>
@@ -11,6 +13,7 @@
 <a href="?mf=#node|short#;path=/">manifest</a>
 #archives%archiveentry#
 <a type="application/rss+xml" href="?style=rss">rss</a>
+<a type="application/atom+xml" href="#url#atom-log" title="Atom feed for #repo|escape#">atom</a>
 </div>
 
 <h2>changelog for #repo|escape#</h2>
--- a/templates/old/filelog.tmpl
+++ b/templates/old/filelog.tmpl
@@ -1,5 +1,7 @@
 #header#
 <title>#repo|escape#: #file|escape# history</title>
+<link rel="alternate" type="application/atom+xml"
+   href="#url#atom-log/tip/#file|urlescape#" title="Atom feed for #repo|escape#:#file#">
 <link rel="alternate" type="application/rss+xml"
    href="?fl=0;file=#file|urlescape#;style=rss" title="RSS feed for #repo|escape#:#file#">
 </head>
@@ -13,6 +15,7 @@
 <a href="?f=#node|short#;file=#file|urlescape#">file</a>
 <a href="?fa=#node|short#;file=#file|urlescape#">annotate</a>
 <a type="application/rss+xml" href="?fl=0;file=#file|urlescape#;style=rss">rss</a>
+<a type="application/atom+xml" href="#url#atom-log/tip/#file|urlescape#" title="Atom feed for #repo|escape#:#file#">atom</a>
 </div>
 
 <h2>#file|escape# revision history</h2>
--- a/templates/old/map
+++ b/templates/old/map
@@ -46,7 +46,7 @@ filediffparent = '<tr><th class="parent"
 filelogparent = '<tr><th>parent #rev#:</th><td><a href="?f=#node|short#;file=#file|urlescape#">#node|short#</a></td></tr>'
 filediffchild = '<tr><th class="child">child #rev#:</th><td class="child"><a href="?cs=#node|short#">#node|short#</a></td></tr>'
 filelogchild = '<tr><th>child #rev#:</th><td><a href="?f=#node|short#;file=#file|urlescape#">#node|short#</a></td></tr>'
-indexentry = '<tr class="parity#parity#"><td><a href="#url#">#name|escape#</a></td><td>#description#</td><td>#contact|obfuscate#</td><td class="age">#lastchange|age# ago</td><td class="indexlinks"><a href="#url#?cl=tip;style=rss">RSS</a> #archives%archiveentry#</td></tr>'
+indexentry = '<tr class="parity#parity#"><td><a href="#url#">#name|escape#</a></td><td>#description#</td><td>#contact|obfuscate#</td><td class="age">#lastchange|age# ago</td><td class="indexlinks"><a href="#url#?cl=tip;style=rss">RSS</a> <a href="#url#atom-log">Atom</a> #archives%archiveentry#</td></tr>'
 index = index.tmpl
 archiveentry = '<a href="#url#?ca=#node|short#;type=#type|urlescape#">#type|escape#</a> '
 notfound = notfound.tmpl
--- a/templates/old/shortlog.tmpl
+++ b/templates/old/shortlog.tmpl
@@ -1,5 +1,7 @@
 #header#
 <title>#repo|escape#: shortlog</title>
+<link rel="alternate" type="application/atom+xml"
+   href="#url#atom-log" title="Atom feed for #repo|escape#">
 <link rel="alternate" type="application/rss+xml"
    href="?cmd=changelog;style=rss" title="RSS feed for #repo|escape#">
 </head>
@@ -11,6 +13,7 @@
 <a href="?mf=#node|short#;path=/">manifest</a>
 #archives%archiveentry#
 <a type="application/rss+xml" href="?style=rss">rss</a>
+<a type="application/atom+xml" href="#url#atom-log" title="Atom feed for #repo|escape#">atom</a>
 </div>
 
 <h2>shortlog for #repo|escape#</h2>
--- a/templates/old/tags.tmpl
+++ b/templates/old/tags.tmpl
@@ -1,5 +1,7 @@
 #header#
 <title>#repo|escape#: tags</title>
+<link rel="alternate" type="application/atom+xml"
+   href="#url#atom-tags" title="Atom feed for #repo|escape#: tags">
 <link rel="alternate" type="application/rss+xml"
    href="?cmd=tags;style=rss" title="RSS feed for #repo|escape#: tags">
 </head>
@@ -10,6 +12,7 @@
 <a href="?sl=tip">shortlog</a>
 <a href="?mf=#node|short#;path=/">manifest</a>
 <a type="application/rss+xml" href="?cmd=tags;style=rss">rss</a>
+<a type="application/atom+xml" href="#url#atom-tags">atom</a>
 </div>
 
 <h2>tags:</h2>
--- a/templates/shortlog.tmpl
+++ b/templates/shortlog.tmpl
@@ -1,5 +1,7 @@
 #header#
 <title>#repo|escape#: shortlog</title>
+<link rel="alternate" type="application/atom+xml"
+   href="#url#atom-log" title="Atom feed for #repo|escape#">
 <link rel="alternate" type="application/rss+xml"
    href="#url#rss-log" title="RSS feed for #repo|escape#">
 </head>
@@ -11,6 +13,7 @@
 <a href="#url#file/#node|short#/{sessionvars%urlparameter}">manifest</a>
 #archives%archiveentry#
 <a type="application/rss+xml" href="#url#rss-log">rss</a>
+<a type="application/rss+xml" href="#url#atom-log" title="Atom feed for #repo|escape#">atom</a>
 </div>
 
 <h2>shortlog for #repo|escape#</h2>
--- a/templates/tags.tmpl
+++ b/templates/tags.tmpl
@@ -1,5 +1,7 @@
 #header#
 <title>#repo|escape#: tags</title>
+<link rel="alternate" type="application/atom+xml"
+   href="#url#atom-tags" title="Atom feed for #repo|escape#: tags">
 <link rel="alternate" type="application/rss+xml"
    href="#url#rss-tags" title="RSS feed for #repo|escape#: tags">
 </head>
@@ -10,6 +12,7 @@
 <a href="#url#shortlog{sessionvars%urlparameter}">shortlog</a>
 <a href="#url#file/#node|short#/{sessionvars%urlparameter}">manifest</a>
 <a type="application/rss+xml" href="#url#rss-tags">rss</a>
+<a type="application/atom+xml" href="#url#atom-tags">atom</a>
 </div>
 
 <h2>tags:</h2>