[Answer]-Return items from RSS feed in Django Templatetags

1đź‘Ť

âś…

This code looks highly suspect:

    for entry in feed.entries:
        entrylist[entry.title]

Shouldn’t it be something like this?

    for entry in feed.entries:
        entrylist[entry.title] = entry     # or some value

As it is right now you are trying to index into an empty dictionary and are thus getting a KeyError exception.

But I’m still not sure what you are trying to do. Here are 2 ideas that come to mind that may get you started.

Idea one: it sort of looks like you should write an inclusion tag.

Something like (untested):

@register.inclusion_tag('feed_entries.html'):
def feed_entries():
    feed = feedparser.parse('example.rss')
    return {'items': feed}

And in feed_entries.html

{% for item in items %}
<p> {{ item }} </p>
{% endfor %}

Then, in some random template where you want the list of items displayed:

{% load feed_tags %}
...
<p>Here are the latest entries:</p>
{% feed_entries %}
...

This is assuming feed contains a list of items you want to render somehow. Thus, whenever you use {% feed_entries %} in a template, your snippet of Python is called, it takes the returned dictionary and renders the feed_entries.html template, and the resulting HTML is placed wherever you wrote {% feed_entries %}.

Idea two: If you really want your tag to return a list of items, you could use an assignment tag:

@register.assignment_tag
def feed_entries():
    return feedparser.parse('example.rss')

Then in your template you have to “catch” the result of this tag (the list of items):

{% feed_entries as items %}
{% for item in items %}
    <p>{{ item }}</p>
{% endfor %}

But that means you’ll have to duplicate the “as” and for-loop stuff in every template. The inclusion tag may save you typing and maintenance if you use it in many templates. But if you wanted to render the list differently in each template it would be more flexible. Say you want it in a list of <p> tags in one, but in a <ul> in another.

👤Brian Neal

Leave a comment