diff --git a/django/contrib/syndication/views.py b/django/contrib/syndication/views.py
index cec204d..4d34e84 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 de32b9f..504ec89 100644
a
|
b
|
class SyndicationFeed(object):
|
86 | 86 | "Base class for all syndication feeds. Subclasses should provide write()" |
87 | 87 | def __init__(self, title, link, description, language=None, author_email=None, |
88 | 88 | author_name=None, author_link=None, subtitle=None, categories=None, |
89 | | feed_url=None, feed_copyright=None, feed_guid=None, ttl=None, **kwargs): |
| 89 | feed_url=None, feed_copyright=None, feed_guid=None, ttl=None, stylesheets=None, **kwargs): |
90 | 90 | to_unicode = lambda s: force_text(s, strings_only=True) |
91 | 91 | if categories: |
92 | 92 | categories = [force_text(c) for c in categories] |
93 | 93 | if ttl is not None: |
94 | 94 | # Force ints to unicode |
95 | 95 | ttl = force_text(ttl) |
| 96 | if stylesheets: |
| 97 | stylesheets = [iri_to_uri(s) for s in stylesheets] |
96 | 98 | self.feed = { |
97 | 99 | 'title': to_unicode(title), |
98 | 100 | 'link': iri_to_uri(link), |
… |
… |
class SyndicationFeed(object):
|
107 | 109 | 'feed_copyright': to_unicode(feed_copyright), |
108 | 110 | 'id': feed_guid or link, |
109 | 111 | 'ttl': ttl, |
| 112 | 'stylesheets': stylesheets or (), |
110 | 113 | } |
111 | 114 | self.feed.update(kwargs) |
112 | 115 | self.items = [] |
… |
… |
class RssFeed(SyndicationFeed):
|
219 | 222 | def write(self, outfile, encoding): |
220 | 223 | handler = SimplerXMLGenerator(outfile, encoding) |
221 | 224 | handler.startDocument() |
| 225 | for s in self.feed['stylesheets']: |
| 226 | # http://www.w3.org/TR/xml-stylesheet/ |
| 227 | handler.processingInstruction('xml-stylesheet', 'type="text/css" href="%s"' % s) |
222 | 228 | handler.startElement("rss", self.rss_attributes()) |
223 | 229 | handler.startElement("channel", self.root_attributes()) |
224 | 230 | self.add_root_elements(handler) |
diff --git a/docs/ref/contrib/syndication.txt b/docs/ref/contrib/syndication.txt
index 9a0fb58..74d3fd5 100644
a
|
b
|
Atom feeds require a ``<link rel="self">`` that defines the feed's current
|
327 | 327 | location. The syndication framework populates this automatically, using the |
328 | 328 | domain of the current site according to the :setting:`SITE_ID` setting. |
329 | 329 | |
| 330 | Stylesheets |
| 331 | ----------- |
| 332 | |
| 333 | .. versionadded:: 1.7 |
| 334 | |
| 335 | RSS feeds support the inclusion of stylesheets via the ``stylesheets`` |
| 336 | attribute, as a sequence of stylesheets to be added to the feed. |
| 337 | |
330 | 338 | Publishing Atom and RSS feeds in tandem |
331 | 339 | --------------------------------------- |
332 | 340 | |
… |
… |
This example illustrates all possible attributes and methods for a
|
591 | 599 | |
592 | 600 | ttl = 600 # Hard-coded Time To Live. |
593 | 601 | |
| 602 | stylesheets = ('http://www.example.com/example.css',) # Hard-coded stylesheets to be added to feed |
| 603 | |
594 | 604 | # ITEMS -- One of the following three is required. The framework looks |
595 | 605 | # for them in this order. |
596 | 606 | |
… |
… |
They share this interface:
|
918 | 928 | * ``feed_copyright`` |
919 | 929 | * ``feed_guid`` |
920 | 930 | * ``ttl`` |
| 931 | * ``stylesheets`` |
921 | 932 | |
922 | 933 | Any extra keyword arguments you pass to ``__init__`` will be stored in |
923 | 934 | ``self.feed`` for use with `custom feed generators`_. |
924 | 935 | |
925 | | All parameters should be Unicode objects, except ``categories``, which |
926 | | should be a sequence of Unicode objects. |
| 936 | All parameters should be Unicode objects, except ``categories`` and |
| 937 | ``stylesheets``, which should be sequences of Unicode objects. |
927 | 938 | |
928 | 939 | :meth:`.SyndicationFeed.add_item` |
929 | 940 | Add an item to the feed with the given parameters. |
diff --git a/tests/syndication/feeds.py b/tests/syndication/feeds.py
index f8ffb4b..08b8aaf 100644
a
|
b
|
class TestRss2Feed(views.Feed):
|
25 | 25 | categories = ('python', 'django') |
26 | 26 | feed_copyright = 'Copyright (c) 2007, Sally Smith' |
27 | 27 | ttl = 600 |
| 28 | stylesheets = ('http://www.example.com/example.css',) |
28 | 29 | |
29 | 30 | def items(self): |
30 | 31 | return Entry.objects.all() |
diff --git a/tests/syndication/tests.py b/tests/syndication/tests.py
index 8bc6b04..39b927e 100644
a
|
b
|
class SyndicationFeedTest(FeedTestCase):
|
51 | 51 | feed = feed_elem[0] |
52 | 52 | self.assertEqual(feed.getAttribute('version'), '2.0') |
53 | 53 | |
| 54 | # Verify document has a stylesheet element (processing instruction <?xml-stylesheet ... ?>) |
| 55 | self.assertEqual(doc.firstChild.target, 'xml-stylesheet') |
| 56 | self.assertEqual(doc.firstChild.data, 'type="text/css" href="http://www.example.com/example.css"') |
| 57 | |
54 | 58 | # Making sure there's only one `channel` element w/in the |
55 | 59 | # `rss` element. |
56 | 60 | chan_elem = feed.getElementsByTagName('channel') |