#**
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  The ASF licenses this file to You
  under the Apache License, Version 2.0 (the "License"); you may not
  use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.  For additional information regarding
  copyright in this work, please see the NOTICE file in the top level
  directory of this distribution.

*#<?xml version="1.0" encoding='utf-8'?>
#showFirefoxFeedWorkaround()
#if($config.feedStyle)<?xml-stylesheet type="text/xsl" href="$url.absoluteSite/roller-ui/styles/atom.xsl" media="screen"?>#end
#set($pager = $model.commentsPager)
<feed xmlns="http://www.w3.org/2005/Atom">
    <title type="html">$utils.escapeXML($model.weblog.name) (Comments)</title>
    <id>$url.feed.comments.atom</id>
    <link rel="alternate" type="text/html" href="$url.home" />
    <link rel="self" type="application/atom+xml" href="$url.feed.comments.atom($model.categoryName, $model.excerpts)" />
    #if($config.feedHistoryEnabled)
        #showFeedHistory($pager)
    #end
    <updated>$utils.formatIso8601Date($model.weblog.lastModified)</updated>
    <generator uri="http://roller.apache.org" version="$config.rollerVersion">Apache Roller</generator>
    #showCommentsAtom10($pager.items)
</feed>

