|
|
User Guide to django-atompub
This covers r33 and later of atom.py.
To generate an atom feed with django-atompub, firstly download atom.py and put it somewhere in your python path.
Then, create a content provider class that will tie your models to the atom data model. This class should extend Feed in the above atom module and then implement a variety of methods (described below) to provide data to the feed generator.
Finally, add something like the following to your urls.py where MyFeed is the content provider class you created above.
urlpatterns = patterns('',
(r"^feeds/(.*)/$", "django.contrib.syndication.views.feed", {
"feed_dict": {
"my_feed": MyFeed,
}
}),
)See the source for an initial example, but I am working on one more appropriate as an example (rather than for testing).
Note: If you are already generating a feed with Django's existing syndication framework see LegacyGuide.
Feed Content Provider
Your Feed subclass needs to implement as many of the following as you need to convey data from your models to the feed generator. Note that the feed_* fields may be implemented as a method or merely as an attribute. e.g.
class MyFeed(Feed):
def feed_title(self):
return my_blog.title
...will work the same as
class MyFeed(Feed):
feed_title = my_blog title
...(for an explanation of the variants taking an obj parameter, see parameterized feeds below)
- feed_id or feed_id(self) or feed_id(self, obj) — required URI
- feed_title or feed_title(self) or feed_title(self, obj) — required text construct (see below)
- feed_subtitle or feed_subtitle(self) or feed_subtitle(self, obj) — text construct (see below)
- feed_icon or feed_icon(self) or feed_icon(self, obj) — URI
- feed_logo or feed_logo(self) or feed_logo(self, obj) — URI
- feed_updated or feed_updated(self) or feed_updated(self, obj) — datetime
- feed_authors or feed_authors(self) or feed_authors(self, obj) — iterable of person constructs (see below)
- feed_contributors or feed_contributors(self) or feed_contributors(self, obj) — iterable of person constructs (see below)
- feed_categories or feed_categories(self) or feed_categories(self, obj) — iterable of category constructs (see below)
- feed_links or feed_links(self) or feed_links(self, obj) — iterable of link constructs (see below)
- feed_rights or feed_rights(self) or feed_rights(self, obj) — text construct (see below)
- feed_extra_attrs or feed_extra_attrs(self) or feed_extra_attrs(self, obj) — dictionary of extra attributes to add to feed element
- items or items(self) or items(self, obj) — required should return an iterable over the item objects that will, in turn be individual passed into the following methods
- item_id(self, item) — required URI
- item_title(self, item) — required text construct (see below)
- item_updated(self, item) — required datetime
- item_published(self, item) — datetime
- item_rights(self, item) — text construct (see below)
- item_source(self, item) — source construct (see below)
- item_summary(self, item) — text construct (see below)
- item_content(self, item) — content construct (see below)
- item_categories(self, item) — iterable of category constructs (see below)
- item_links(self, item) — iterable of link constructs (see below)
- item_authors(self, item) — iterable of person constructs (see below)
- item_contributors(self, item) — iterable of person constructs (see below)
- item_extra_attrs(self, item) — dictionary of extra attributes to add to entry element
Note that future versions of django-atompub will include a base class that will provide defaults for some of the above fields. It may also be possible to provide a bridge between legacy atom feed code and this new feed generator.
Parameterized Feeds
Say you want to provide a feed for each of your blog tags (for example at /feed/tag/{tag}/). You set up your url pattern the same:
urlpatterns = patterns('',
(r"^feeds/(.*)/$", "django.contrib.syndication.views.feed", {
"feed_dict": {
"tag": TagFeed,
}
}),
)but you implement an extra method on your TagFeed called get_object(params).
params will be a list of the components of the URL following "tag". So /tag/foo/bar would result in params being passed in as ['foo', 'bar'].
get_object should then return some object and this object will be passed in an extra argument to each of the feed_*() methods as well as items(). This way your feed_*() methods and items() can return a value appropriate to the object (and hence the particular feed requested) instead of being hard-coded.
Feed Validation
RFC 4287 places certain constraints on combinations of elements and their contents. For example,
- if a feed has no author, each of the entries must have an author (possibly in the source element)
- if no there is content, an entry must have alternate link
- external content (i.e. content with a src attribute) requires the entry has a summary
By default, feeds are validated against these and many other constraints described in RFC 4287. This check greatly reduces the chance of producing an invalid atom feed. If a feed violates a constraint, an atom.ValidationError will be thrown.
You can turn this checking off by setting VALIDATE on your Feed content provider class to False:
class MyFeed(Feed):
VALIDATE = False
...Constructs
Text Construct
A field marked text construct above can just equal or return a string:
feed_title = "My Blog"
or
def item_title(self, item):
return item.headlineHowever, if the text is html or xhtml, you can specify this by returning a type, text tuple:
def feed_subtitle(self):
return "html", "An <b>awesome</b> blog"Person Construct
A person construct is a dictionary that, at the very least has a name key. It can also have a uri key and an email key. All fields above that return person constructs do so as an iterable. Examples:
feed_authors = [{"name": "James Tauber"}]or
def item_contributors(self, item):
for contributor in item.contributors.all():
yield {"name": contributor.full_name, "email": contributor.email_address}Link Construct
A link construct is a dictionary that, at the very least has an href key. Other allowable keys include rel, type, hreflang and length. Like person constructs, fields always return iterables of these. Example:
feed_links = [{"rel": "alternate", "href": "http://example.com/blog/"}]Category Construct
A category construct is a dictionary that, at the very least has a term key. Other allowable keys include scheme (whose value is a URI) and label. Like link constructs, fields always return iterables of these. Example:
feed_categories = [
{"term": "django"},
{"term": "atom"},
]Source Construct
A source construct is a dictionary whose items reflect certain fields on the source feed from which the entry was taken. Hence the appropriate keys are id, title, subtitle, icon, logo, updated, authors, contributors, categories, links, rights and the values as one would expect for the equivalent feed_* field in each case.
Note that no keys are required, although an id, title and link rel="alternate" are probably all good ideas.
Content Construct
Like a text construct, if your content is just text, you can simple return a string. However, if your content is html, xhtml or out-of-line or if you simply want to provide additional attributes like xml:lang a content construct field can return an attributes, content tuple where attributes is a dictionary that includes any of type, src, xml:lang or xml:base keys. Examples:
def item_content(self, item):
return item.bodyor
def item_content(self, item):
return {"type": "html", "xml:base": "http://example.com/"}, item.body.to_html()or
def item_content(self, item):
return {"type": "image/jpeg", "src": item.url}, ""
Sign in to add a comment
