diff --git a/django/contrib/syndication/views.py b/django/contrib/syndication/views.py
index e4ff6e6..cb453df 100644
|
a
|
b
|
class Feed(object):
|
| 138 | 138 | feed_copyright=self.__get_dynamic_attr('feed_copyright', obj), |
| 139 | 139 | feed_guid=self.__get_dynamic_attr('feed_guid', obj), |
| 140 | 140 | ttl=self.__get_dynamic_attr('ttl', obj), |
| | 141 | stylesheets = self.__get_dynamic_attr('stylesheets', obj), |
| 141 | 142 | **self.feed_extra_kwargs(obj) |
| 142 | 143 | ) |
| 143 | 144 | |
diff --git a/django/utils/feedgenerator.py b/django/utils/feedgenerator.py
index 52c0ecc..ac94d37 100644
|
a
|
b
|
class SyndicationFeed(object):
|
| 87 | 87 | "Base class for all syndication feeds. Subclasses should provide write()" |
| 88 | 88 | def __init__(self, title, link, description, language=None, author_email=None, |
| 89 | 89 | author_name=None, author_link=None, subtitle=None, categories=None, |
| 90 | | feed_url=None, feed_copyright=None, feed_guid=None, ttl=None, **kwargs): |
| | 90 | feed_url=None, feed_copyright=None, feed_guid=None, ttl=None, stylesheets=None, **kwargs): |
| 91 | 91 | to_unicode = lambda s: force_text(s, strings_only=True) |
| 92 | 92 | if categories: |
| 93 | 93 | categories = [force_text(c) for c in categories] |
| 94 | 94 | if ttl is not None: |
| 95 | 95 | # Force ints to unicode |
| 96 | 96 | ttl = force_text(ttl) |
| | 97 | if stylesheets: |
| | 98 | stylesheets = [iri_to_uri(s) for s in stylesheets] |
| 97 | 99 | self.feed = { |
| 98 | 100 | 'title': to_unicode(title), |
| 99 | 101 | 'link': iri_to_uri(link), |
| … |
… |
class SyndicationFeed(object):
|
| 108 | 110 | 'feed_copyright': to_unicode(feed_copyright), |
| 109 | 111 | 'id': feed_guid or link, |
| 110 | 112 | 'ttl': ttl, |
| | 113 | 'stylesheets': stylesheets or (), |
| 111 | 114 | } |
| 112 | 115 | self.feed.update(kwargs) |
| 113 | 116 | self.items = [] |
| … |
… |
class RssFeed(SyndicationFeed):
|
| 223 | 226 | def write(self, outfile, encoding): |
| 224 | 227 | handler = SimplerXMLGenerator(outfile, encoding) |
| 225 | 228 | handler.startDocument() |
| | 229 | for s in self.feed['stylesheets']: |
| | 230 | # http://www.w3.org/TR/xml-stylesheet/ |
| | 231 | handler.processingInstruction('xml-stylesheet', 'type="text/css" href="%s"' % s) |
| 226 | 232 | handler.startElement("rss", self.rss_attributes()) |
| 227 | 233 | handler.startElement("channel", self.root_attributes()) |
| 228 | 234 | self.add_root_elements(handler) |
| … |
… |
class Atom1Feed(SyndicationFeed):
|
| 322 | 328 | def write(self, outfile, encoding): |
| 323 | 329 | handler = SimplerXMLGenerator(outfile, encoding) |
| 324 | 330 | handler.startDocument() |
| | 331 | for s in self.feed['stylesheets']: |
| | 332 | # http://www.w3.org/TR/xml-stylesheet/ |
| | 333 | handler.processingInstruction('xml-stylesheet', 'type="text/css" href="%s"' % s) |
| 325 | 334 | handler.startElement('feed', self.root_attributes()) |
| 326 | 335 | self.add_root_elements(handler) |
| 327 | 336 | self.write_items(handler) |
diff --git a/docs/ref/contrib/syndication.txt b/docs/ref/contrib/syndication.txt
index 7e31eb0..9a213b6 100644
|
a
|
b
|
Atom feeds require a ``<link rel="self">`` that defines the feed's current
|
| 323 | 323 | location. The syndication framework populates this automatically, using the |
| 324 | 324 | domain of the current site according to the :setting:`SITE_ID` setting. |
| 325 | 325 | |
| | 326 | Stylesheets |
| | 327 | ----------- |
| | 328 | |
| | 329 | .. versionadded:: 1.8 |
| | 330 | |
| | 331 | RSS and Atom feeds support the inclusion of stylesheets via the ``stylesheets`` |
| | 332 | attribute, as a sequence of stylesheets to be added to the feed. |
| | 333 | |
| 326 | 334 | Publishing Atom and RSS feeds in tandem |
| 327 | 335 | --------------------------------------- |
| 328 | 336 | |
| … |
… |
This example illustrates all possible attributes and methods for a
|
| 587 | 595 | |
| 588 | 596 | ttl = 600 # Hard-coded Time To Live. |
| 589 | 597 | |
| | 598 | stylesheets = ('http://www.example.com/example.css',) # Hard-coded stylesheets to be added to feed |
| | 599 | |
| 590 | 600 | # ITEMS -- One of the following three is required. The framework looks |
| 591 | 601 | # for them in this order. |
| 592 | 602 | |
| … |
… |
They share this interface:
|
| 914 | 924 | * ``feed_copyright`` |
| 915 | 925 | * ``feed_guid`` |
| 916 | 926 | * ``ttl`` |
| | 927 | * ``stylesheets`` |
| 917 | 928 | |
| 918 | 929 | Any extra keyword arguments you pass to ``__init__`` will be stored in |
| 919 | 930 | ``self.feed`` for use with `custom feed generators`_. |
| 920 | 931 | |
| 921 | | All parameters should be Unicode objects, except ``categories``, which |
| 922 | | should be a sequence of Unicode objects. |
| | 932 | All parameters should be Unicode objects, except ``categories`` and |
| | 933 | ``stylesheets``, which should be sequences of Unicode objects. |
| 923 | 934 | |
| 924 | 935 | :meth:`.SyndicationFeed.add_item` |
| 925 | 936 | Add an item to the feed with the given parameters. |
diff --git a/tests/syndication_tests/tests.py b/tests/syndication_tests/tests.py
index 8da3d5e..33952ea 100644
|
a
|
b
|
class SyndicationFeedTest(FeedTestCase):
|
| 70 | 70 | feed = feed_elem[0] |
| 71 | 71 | self.assertEqual(feed.getAttribute('version'), '2.0') |
| 72 | 72 | |
| | 73 | # Verify document has a stylesheet element (processing instruction <?xml-stylesheet ... ?>) |
| | 74 | self.assertEqual(doc.firstChild.target, 'xml-stylesheet') |
| | 75 | self.assertEqual(doc.firstChild.data, 'type="text/css" href="http://www.example.com/example.css"') |
| | 76 | |
| 73 | 77 | # Making sure there's only one `channel` element w/in the |
| 74 | 78 | # `rss` element. |
| 75 | 79 | chan_elem = feed.getElementsByTagName('channel') |