Index: django/contrib/gis/feeds.py
===================================================================
--- django/contrib/gis/feeds.py	(revision 0)
+++ django/contrib/gis/feeds.py	(revision 0)
@@ -0,0 +1,80 @@
+from django.contrib.syndication.feeds import Feed as BaseFeed, FeedDoesNotExist
+from django.utils.feedgenerator import Atom1Feed, Rss201rev2Feed
+
+def georss_coords(coords):
+    """
+    In GeoRSS coordinate pairs are ordered by lat/lon and separated by
+    a single white space.  Given a tuple of coordinates, this will return
+    a unicode GeoRSS representation.
+    """
+    return u' '.join([u'%f %f' % (coord[1], coord[0]) for coord in coords])
+
+def add_georss_element(handler, item):
+    """
+    This routine adds a GeoRSS XML element for the given item. 
+    """
+    # Getting the Geometry object.
+    geom = item.get('geometry', None)
+    if not geom is None:
+        if isinstance(geom, (list, tuple)):
+            # Special case if a bounding box/extent was bassed in as a 2-tuple
+            # ( (X0, Y0), (X1, Y1) ) or a 4-tuple (X0, Y0, X1, Y1).
+            if len(geom) == 2:
+                handler.addQuickElement(u'georss:box', georss_coords(geom))
+            elif len(geom) == 4:
+                handler.addQuickElement(u'georss:box', georss_coords((geom[:2], geom[2:])))
+            else:
+                raise ValueError
+        else:
+            gtype = str(geom.geom_type).lower()
+            if gtype == 'point':
+                handler.addQuickElement(u'georss:point', georss_coords((geom.coords,)))
+            elif gtype in ('linestring', 'linearring'):
+                handler.addQuickElement(u'georss:line', georss_coords(geom.coords))
+            elif gtype in ('polygon'):
+                # Only support the exterior ring.
+                handler.addQuickElement(u'georss:polygon', georss_coords(geom[0].coords))
+            else:
+                raise TypeError('Geometry type "%s" not supported.' % geom.geom_type)
+
+class GeoRSSFeed(Rss201rev2Feed):
+    def rss_attributes(self):
+        attrs = super(GeoRSSFeed, self).rss_attributes()
+        attrs[u'xmlns:georss'] = u'http://www.georss.org/georss'
+        return attrs
+
+    def add_item_elements(self, handler, item):
+        super(GeoRSSFeed, self).add_item_elements(handler, item)
+        add_georss_element(handler, item)
+
+    def add_root_elements(self, handler):
+        super(GeoRSSFeed, self).add_root_elements(handler)
+        add_georss_element(handler, self.feed)
+
+class GeoAtom1Feed(Atom1Feed):
+    def root_attributes(self):
+        attrs = super(GeoAtom1Feed, self).root_attributes()
+        attrs[u'xmlns:georss'] = u'http://www.georss.org/georss'
+        return attrs
+
+    def add_item_elements(self, handler, item):
+        super(GeoAtom1Feed, self).add_item_elements(handler, item)
+        add_georss_element(handler, item)
+
+    def add_root_elements(self, handler):
+        super(GeoAtom1Feed, self).add_root_elements(handler)
+        add_georss_element(handler, self.feed)
+        
+class Feed(BaseFeed):
+    feed_type = GeoRSSFeed
+    #feed_type = GeoAtom1Feed
+
+    def get_feed_kwargs(self, obj):
+        kwargs = super(Feed, self).get_feed_kwargs(obj)
+        kwargs['geometry'] = self.__get_dynamic_attr('geometry', obj)
+        return kwargs
+
+    def get_item_kwargs(self, item):
+        kwargs = super(Feed, self).get_item_kwargs(item)
+        kwargs['geometry'] = self.__get_dynamic_attr('item_geometry', item)
+        return kwargs
Index: django/contrib/syndication/feeds.py
===================================================================
--- django/contrib/syndication/feeds.py	(revision 8335)
+++ django/contrib/syndication/feeds.py	(working copy)
@@ -62,6 +62,81 @@
     def get_object(self, bits):
         return None
 
+    def get_feed_kwargs(self, obj):
+        """
+        Returns the keyword arguments to instatiate the `SyndicationFeed`
+        class specified by the `feed_type` attribute.
+        """
+        return {
+            'title' : self.__get_dynamic_attr('title', obj),
+            'subtitle' : self.__get_dynamic_attr('subtitle', obj),
+            'link' : add_domain(self.current_site.domain,
+                                self.__get_dynamic_attr('link', obj)),
+            'description' : self.__get_dynamic_attr('description', obj),
+            'language' : settings.LANGUAGE_CODE.decode(),
+            'feed_url' : add_domain(self.current_site.domain,
+                                  self.__get_dynamic_attr('feed_url', obj)),
+            'author_name' : self.__get_dynamic_attr('author_name', obj),
+            'author_link' : self.__get_dynamic_attr('author_link', obj),
+            'author_email' : self.__get_dynamic_attr('author_email', obj),
+            'categories' : self.__get_dynamic_attr('categories', obj),
+            'feed_copyright' : self.__get_dynamic_attr('feed_copyright', obj),
+            'feed_guid' : self.__get_dynamic_attr('feed_guid', obj),
+            'ttl' : self.__get_dynamic_attr('ttl', obj),
+            }
+
+    def get_item_kwargs(self, item):
+        """
+        Returns the keyword arguments to pass to the `add_item` method of the
+        `SyndicationFeed` instance (specified by the `feed_type` attribute).
+        """
+        link = add_domain(self.current_site.domain, self.__get_dynamic_attr('item_link', item))
+        enc = None
+        enc_url = self.__get_dynamic_attr('item_enclosure_url', item)
+        if enc_url:
+            enc = feedgenerator.Enclosure(
+                url = smart_unicode(enc_url),
+                length = smart_unicode(self.__get_dynamic_attr('item_enclosure_length', item)),
+                mime_type = smart_unicode(self.__get_dynamic_attr('item_enclosure_mime_type', item))
+                )
+        author_name = self.__get_dynamic_attr('item_author_name', item)
+        if author_name is not None:
+            author_email = self.__get_dynamic_attr('item_author_email', item)
+            author_link = self.__get_dynamic_attr('item_author_link', item)
+        else:
+            author_email = author_link = None
+
+        pubdate = self.__get_dynamic_attr('item_pubdate', item)
+        if pubdate:
+            now = datetime.now()
+            utcnow = datetime.utcnow()
+
+            # Must always subtract smaller time from larger time here.
+            if utcnow > now:
+                sign = -1
+                tzDifference = (utcnow - now)
+            else:
+                sign = 1
+                tzDifference = (now - utcnow)
+
+            # Round the timezone offset to the nearest half hour.
+            tzOffsetMinutes = sign * ((tzDifference.seconds / 60 + 15) / 30) * 30
+            tzOffset = timedelta(minutes=tzOffsetMinutes)
+            pubdate = pubdate.replace(tzinfo=FixedOffset(tzOffset))
+
+        return {'title' : self.title_tmp.render(RequestContext(self.request, {'obj': item, 'site': self.current_site})),
+                'link' : link,
+                'description' : self.description_tmp.render(RequestContext(self.request, {'obj': item, 'site': self.current_site})),
+                'unique_id' : self.__get_dynamic_attr('item_guid', item, link),
+                'enclosure' : enc,
+                'pubdate' : pubdate,
+                'author_name' : author_name,
+                'author_email' : author_email,
+                'author_link' : author_link,
+                'categories' : self.__get_dynamic_attr('item_categories', item),
+                'item_copyright' : self.__get_dynamic_attr('item_copyright', item),
+                }
+
     def get_feed(self, url=None):
         """
         Returns a feedgenerator.DefaultFeed object, fully populated, for
@@ -77,86 +152,26 @@
         except ObjectDoesNotExist:
             raise FeedDoesNotExist
 
+        # Getting the current site.
         if Site._meta.installed:
-            current_site = Site.objects.get_current()
+            self.current_site = Site.objects.get_current()
         else:
-            current_site = RequestSite(self.request)
-        
-        link = self.__get_dynamic_attr('link', obj)
-        link = add_domain(current_site.domain, link)
+            self.current_site = RequestSite(self.request)
 
-        feed = self.feed_type(
-            title = self.__get_dynamic_attr('title', obj),
-            subtitle = self.__get_dynamic_attr('subtitle', obj),
-            link = link,
-            description = self.__get_dynamic_attr('description', obj),
-            language = settings.LANGUAGE_CODE.decode(),
-            feed_url = add_domain(current_site.domain,
-                                  self.__get_dynamic_attr('feed_url', obj)),
-            author_name = self.__get_dynamic_attr('author_name', obj),
-            author_link = self.__get_dynamic_attr('author_link', obj),
-            author_email = self.__get_dynamic_attr('author_email', obj),
-            categories = self.__get_dynamic_attr('categories', obj),
-            feed_copyright = self.__get_dynamic_attr('feed_copyright', obj),
-            feed_guid = self.__get_dynamic_attr('feed_guid', obj),
-            ttl = self.__get_dynamic_attr('ttl', obj),
-        )
+        # Initializing the feed.
+        feed = self.feed_type(**self.get_feed_kwargs(obj))
 
+        # Getting instances of the title and description templates.
         try:
-            title_tmp = loader.get_template(self.title_template_name)
+            self.title_tmp = loader.get_template(self.title_template_name)
         except TemplateDoesNotExist:
-            title_tmp = Template('{{ obj }}')
+            self.title_tmp = Template('{{ obj }}')
         try:
-            description_tmp = loader.get_template(self.description_template_name)
+            self.description_tmp = loader.get_template(self.description_template_name)
         except TemplateDoesNotExist:
-            description_tmp = Template('{{ obj }}')
+            self.description_tmp = Template('{{ obj }}')
 
+        # Creating the entry for each item.
         for item in self.__get_dynamic_attr('items', obj):
-            link = add_domain(current_site.domain, self.__get_dynamic_attr('item_link', item))
-            enc = None
-            enc_url = self.__get_dynamic_attr('item_enclosure_url', item)
-            if enc_url:
-                enc = feedgenerator.Enclosure(
-                    url = smart_unicode(enc_url),
-                    length = smart_unicode(self.__get_dynamic_attr('item_enclosure_length', item)),
-                    mime_type = smart_unicode(self.__get_dynamic_attr('item_enclosure_mime_type', item))
-                )
-            author_name = self.__get_dynamic_attr('item_author_name', item)
-            if author_name is not None:
-                author_email = self.__get_dynamic_attr('item_author_email', item)
-                author_link = self.__get_dynamic_attr('item_author_link', item)
-            else:
-                author_email = author_link = None
-
-            pubdate = self.__get_dynamic_attr('item_pubdate', item)
-            if pubdate:
-                now = datetime.now()
-                utcnow = datetime.utcnow()
-
-                # Must always subtract smaller time from larger time here.
-                if utcnow > now:
-                    sign = -1
-                    tzDifference = (utcnow - now)
-                else:
-                    sign = 1
-                    tzDifference = (now - utcnow)
-
-                # Round the timezone offset to the nearest half hour.
-                tzOffsetMinutes = sign * ((tzDifference.seconds / 60 + 15) / 30) * 30
-                tzOffset = timedelta(minutes=tzOffsetMinutes)
-                pubdate = pubdate.replace(tzinfo=FixedOffset(tzOffset))
-
-            feed.add_item(
-                title = title_tmp.render(RequestContext(self.request, {'obj': item, 'site': current_site})),
-                link = link,
-                description = description_tmp.render(RequestContext(self.request, {'obj': item, 'site': current_site})),
-                unique_id = self.__get_dynamic_attr('item_guid', item, link),
-                enclosure = enc,
-                pubdate = pubdate,
-                author_name = author_name,
-                author_email = author_email,
-                author_link = author_link,
-                categories = self.__get_dynamic_attr('item_categories', item),
-                item_copyright = self.__get_dynamic_attr('item_copyright', item),
-            )
+            feed.add_item(**self.get_item_kwargs(item))
         return feed
