Anonymous avatar Anonymous committed fc30ac8

Improved Atom feed-generating framework to output <link rel='self'>. Added a feed_url hook to feedgenerator for this purpose, and changed the syndication Feed and views to use it. Also updated docs.

Comments (0)

Files changed (4)


     item_enclosure_url = None
     feed_type = feedgenerator.DefaultFeed
-    def __init__(self, slug):
+    def __init__(self, slug, feed_url):
         self.slug = slug
+        self.feed_url = feed_url
     def item_link(self, item):
             title = self.__get_dynamic_attr('title', obj),
             link = link,
             description = self.__get_dynamic_attr('description', obj),
-            language = LANGUAGE_CODE.decode()
+            language = LANGUAGE_CODE.decode(),
+            feed_url = add_domain(current_site, self.feed_url),


         raise Http404, "Slug %r isn't registered." % slug
-        feedgen = f(slug).get_feed(param)
+        feedgen = f(slug, request.path).get_feed(param)
     except feeds.FeedDoesNotExist:
         raise Http404, "Invalid feed parameters. Slug %r is valid, but other parameters, or lack thereof, are not." % slug


 class SyndicationFeed:
     "Base class for all syndication feeds. Subclasses should provide write()"
     def __init__(self, title, link, description, language=None, author_email=None,
-            author_name=None, author_link=None, subtitle=None, categories=None):
+            author_name=None, author_link=None, subtitle=None, categories=None,
+            feed_url=None):
         self.feed = {
             'title': title,
             'link': link,
             'author_link': author_link,
             'subtitle': subtitle,
             'categories': categories or (),
+            'feed_url': feed_url,
         self.items = []
             handler.startElement(u"feed", {u"xmlns": self.ns})
         handler.addQuickElement(u"title", self.feed['title'])
-        handler.addQuickElement(u"link", "", {u"href": self.feed['link']})
+        handler.addQuickElement(u"link", "", {u"rel": u"alternate", u"href": self.feed['link']})
+        if self.feed['feed_url'] is not None:
+            handler.addQuickElement(u"link", "", {u"rel": u"self", u"href": self.feed['feed_url']})
         handler.addQuickElement(u"id", self.feed['link'])
         handler.addQuickElement(u"updated", rfc3339_date(self.latest_post_date()).decode('ascii'))
         if self.feed['author_name'] is not None:


 .. _LANGUAGE_CODE setting:
+The ``link`` method/attribute can return either an absolute URL (e.g.
+``"/blog/"``) or a URL with the fully-qualified domain and protocol (e.g.
+``""``). If ``link`` doesn't return the domain,
+the syndication framework will insert the domain of the current site, according
+to your `SITE_ID setting`_.
+Atom feeds require a ``<link rel="self">`` that defines the feed's current
+location. The syndication framework populates this automatically, using the
+domain of the current site according to the SITE_ID setting.
+.. _SITE_ID setting:
 Publishing Atom and RSS feeds in tandem
 They share this interface:
 ``__init__(title, link, description, language=None, author_email=None,``
-``author_name=None, author_link=None, subtitle=None, categories=None)``
+``author_name=None, author_link=None, subtitle=None, categories=None,``
 Initializes the feed with the given metadata, which applies to the entire feed
 (i.e., not just to a specific item in the feed).
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.