Commit 0a8402eb authored by Zbigniew Siciarz's avatar Zbigniew Siciarz Committed by Jacob Kaplan-Moss
Browse files

Test case and docs for custom context data in feeds

Thanks Paul Winkler for the initial patch. (Ref #18112).
parent 4506ae04
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
@@ -100,6 +100,16 @@ class Feed(object):
    def get_object(self, request, *args, **kwargs):
        return None

    def get_context_data(self, **kwargs):
        """
        Returns a dictionary to use as extra context if either
        ``self.description_template`` or ``self.item_template`` are used.

        Default implementation preserves the old behavior
        of using {'obj': item, 'site': current_site} as the context.
        """
        return {'obj': kwargs.get('item'), 'site': kwargs.get('site')}

    def get_feed(self, obj, request):
        """
        Returns a feedgenerator.DefaultFeed object, fully populated, for
@@ -146,12 +156,14 @@ class Feed(object):
                pass

        for item in self.__get_dynamic_attr('items', obj):
            context = self.get_context_data(item=item, site=current_site,
                                            obj=obj, request=request)
            if title_tmp is not None:
                title = title_tmp.render(RequestContext(request, {'obj': item, 'site': current_site}))
                title = title_tmp.render(RequestContext(request, context))
            else:
                title = self.__get_dynamic_attr('item_title', item)
            if description_tmp is not None:
                description = description_tmp.render(RequestContext(request, {'obj': item, 'site': current_site}))
                description = description_tmp.render(RequestContext(request, context))
            else:
                description = self.__get_dynamic_attr('item_description', item)
            link = add_domain(
+54 −0
Original line number Diff line number Diff line
@@ -137,6 +137,51 @@ into those elements.

  See `a complex example`_ below that uses a description template.

  There is also a way to pass additional information to title and description
  templates, if you need to supply more than the two variables mentioned
  before. You can provide your implementation of ``get_context_data`` method
  in your Feed subclass. For example::

    from mysite.models import Article
    from django.contrib.syndication.views import Feed

    class ArticlesFeed(Feed):
        title = "My articles"
        description_template = "feeds/articles.html"

        def items(self):
            return Article.objects.order_by('-pub_date')[:5]

        def get_context_data(self, **kwargs):
            context = super(ArticlesFeed, self).get_context_data(**kwargs)
            context['foo'] = 'bar'
            return context

  And the template:

  .. code-block:: html+django

    Something about {{ foo }}: {{ obj.description }}

  This method will be called once per each item in the list returned by
  ``items()`` with the following keyword arguments:

  * ``item``: the current item. For backward compatibility reasons, the name
    of this context variable is ``{{ obj }}``.

  * ``obj``: the object returned by ``get_object()``. By default this is not
    exposed to the templates to avoid confusion with ``{{ obj }}`` (see above),
    but you can use it in your implementation of ``get_context_data()``.

  * ``site``: current site as described above.

  * ``request``: current request.

  The behavior of ``get_context_data()`` mimics that of
  :ref:`generic views <adding-extra-context>` - you're supposed to call
  ``super()`` to retrieve context data from parent class, add your data
  and return the modified dictionary.

* To specify the contents of ``<link>``, you have two options. For each item
  in ``items()``, Django first tries calling the
  ``item_link()`` method on the
@@ -599,6 +644,15 @@ This example illustrates all possible attributes and methods for a

        item_description = 'A description of the item.' # Hard-coded description.

        def get_context_data(self, **kwargs):
            """
            Returns a dictionary to use as extra context if either
            description_template or item_template are used.

            Default implementation preserves the old behavior
            of using {'obj': item, 'site': current_site} as the context.
            """

        # ITEM LINK -- One of these three is required. The framework looks for
        # them in this order.

+2 −0
Original line number Diff line number Diff line
@@ -188,6 +188,8 @@ Providing a useful ``context_object_name`` is always a good idea. Your
coworkers who design templates will thank you.


.. _adding-extra-context:

Adding extra context
--------------------

+13 −0
Original line number Diff line number Diff line
@@ -97,6 +97,19 @@ class TemplateFeed(TestRss2Feed):
        return "Not in a template"


class TemplateContextFeed(TestRss2Feed):
    """
    A feed to test custom context data in templates for title or description.
    """
    title_template = 'syndication/title_context.html'
    description_template = 'syndication/description_context.html'

    def get_context_data(self, **kwargs):
        context = super(TemplateContextFeed, self).get_context_data(**kwargs)
        context['foo'] = 'bar'
        return context


class NaiveDatesFeed(TestAtomFeed):
    """
    A feed with naive (non-timezone-aware) dates.
+1 −0
Original line number Diff line number Diff line
{{ obj }} (foo is {{ foo }})
 No newline at end of file
Loading