Skip to content

Commit

Permalink
Brought our port of the syndication framework up to speed with the
Browse files Browse the repository at this point in the history
changes in Django 1.2. Fixes #5.
  • Loading branch information
miracle2k committed Aug 29, 2010
1 parent 46606e1 commit 34765ff
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 34 deletions.
37 changes: 17 additions & 20 deletions coffin/contrib/syndication/feeds.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,30 @@
from django.contrib.syndication.feeds import * # merge modules

import sys
from django.contrib.syndication.feeds import Feed as DjangoFeed
from django.contrib.syndication.feeds import Feed as DjangoDeprecatedFeed
from django.contrib.syndication.views import Feed as DjangoNewFeed
from coffin.template import loader as coffin_loader
from django import VERSION as DJANGO_VERSION


class Feed(DjangoFeed):
"""A ``Feed`` implementation that renders it's title and
description templates using Jinja2.
class Feed(DjangoDeprecatedFeed):
"""Django changed the syndication framework in 1.2. This class
represents the old way, ported to Coffin. If you are using 1.2,
you should use the ``Feed`` class in
``coffin.contrib.syndication.views``.
Unfortunately, Django's base ``Feed`` class is not very extensible
in this respect at all. For a real solution, we'd have to essentially
have to duplicate the whole class. So for now, we use this terrible
non-thread safe hack.
Another, somewhat crazy option would be:
* Render the templates ourselves through Jinja2 (possible
introduce new attributes to avoid having to rewrite the
existing ones).
* Make the rendered result available to Django/the superclass by
using a custom template loader using a prefix, say
"feed:<myproject.app.views.MyFeed>". The loader would simply
return the Jinja-rendered template (escaped), the Django template
mechanism would find no nodes and just pass the output through.
Possible even worse than this though.
See also there for some notes on what we are doing here.
"""

def get_feed(self, *args, **kwargs):
parent_module = sys.modules[DjangoFeed.__module__]
if DJANGO_VERSION < (1,2):
parent_module = sys.modules[DjangoDeprecatedFeed.__module__]
else:
# In Django 1.2, our parent DjangoDeprecatedFeed class really
# inherits from DjangoNewFeed, so we need to patch the loader
# in a different module.
parent_module = sys.modules[DjangoNewFeed.__module__]

old_loader = parent_module.loader
parent_module.loader = coffin_loader
try:
Expand Down
36 changes: 36 additions & 0 deletions coffin/contrib/syndication/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from django.contrib.syndication.views import * # merge modules

import sys
from django.contrib.syndication.views import Feed as DjangoFeed
from coffin.template import loader as coffin_loader


class Feed(DjangoFeed):
"""A ``Feed`` implementation that renders it's title and
description templates using Jinja2.
Unfortunately, Django's base ``Feed`` class is not very extensible
in this respect at all. For a real solution, we'd have to essentially
have to duplicate the whole class. So for now, we use this terrible
non-thread safe hack.
Another, somewhat crazy option would be:
* Render the templates ourselves through Jinja2 (possible
introduce new attributes to avoid having to rewrite the
existing ones).
* Make the rendered result available to Django/the superclass by
using a custom template loader using a prefix, say
"feed:<myproject.app.views.MyFeed>". The loader would simply
return the Jinja-rendered template (escaped), the Django template
mechanism would find no nodes and just pass the output through.
Possible even worse than this though.
"""

def get_feed(self, *args, **kwargs):
parent_module = sys.modules[DjangoFeed.__module__]
old_loader = parent_module.loader
parent_module.loader = coffin_loader
try:
return super(Feed, self).get_feed(*args, **kwargs)
finally:
parent_module.loader = old_loader
25 changes: 22 additions & 3 deletions tests/res/apps/feeds_app/feeds.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from coffin.contrib.syndication.feeds import Feed
from coffin.contrib.syndication.feeds import Feed as OldFeed


class TestFeed(Feed):
class TestOldFeed(OldFeed):
title = 'Foo'
link = '/'

Expand All @@ -12,4 +12,23 @@ def item_link(self, item):
return '/item'

title_template = 'feeds_app/feed_title.html'
description_template = 'feeds_app/feed_description.html'
description_template = 'feeds_app/feed_description.html'


try:
from coffin.contrib.syndication.views import Feed as NewFeed
except ImportError:
pass
else:
class TestNewFeed(NewFeed):
title = 'Foo'
link = '/'

def items(self):
return [1,2,3]

def item_link(self, item):
return '/item'

title_template = 'feeds_app/feed_title.html'
description_template = 'feeds_app/feed_description.html'
42 changes: 31 additions & 11 deletions tests/test_contrib.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
def test_syndication():
from django.http import HttpRequest
fake_request = HttpRequest()
fake_request.META['SERVER_NAME'] = 'foo'
fake_request.META['SERVER_PORT'] = 80

from apps.feeds_app.feeds import TestFeed
feedgen = TestFeed('', fake_request).get_feed(None)
s = feedgen.writeString('utf-8')
assert 'JINJA WAS HERE (TITLE)' in s
assert 'JINJA WAS HERE (DESCRIPTION)' in s
from nose.plugins.skip import SkipTest
import django


class TestSyndication:

def test_old(self):
from django.http import HttpRequest
fake_request = HttpRequest()
fake_request.META['SERVER_NAME'] = 'foo'
fake_request.META['SERVER_PORT'] = 80

from apps.feeds_app.feeds import TestOldFeed
feedgen = TestOldFeed('', fake_request).get_feed(None)
s = feedgen.writeString('utf-8')
assert 'JINJA WAS HERE (TITLE)' in s
assert 'JINJA WAS HERE (DESCRIPTION)' in s

def test_new(self):
if django.VERSION < (1,2):
raise SkipTest()

from django.http import HttpRequest
fake_request = HttpRequest()
fake_request.META['SERVER_NAME'] = 'foo'
fake_request.META['SERVER_PORT'] = 80

from apps.feeds_app.feeds import TestNewFeed
response = TestNewFeed()(fake_request)
assert 'JINJA WAS HERE (TITLE)' in response.content
assert 'JINJA WAS HERE (DESCRIPTION)' in response.content

0 comments on commit 34765ff

Please sign in to comment.