Edgewall Software

Changes between Version 46 and Version 47 of GenshiTutorial


Ignore:
Timestamp:
Aug 31, 2007, 12:43:36 AM (17 years ago)
Author:
cmlenz
Comment:

Add Atom feed

Legend:

Unmodified
Added
Removed
Modified
  • GenshiTutorial

    v46 v47  
    815815    <a href="${url('/comment/%s/' % link.id)}">comment</a>
    816816    <ul py:if="link.comments" class="comments">
    817       <li py:for="comment in link.comments">
     817      <li py:for="idx, comment in enumerate(link.comments)" id="comment$idx">
    818818        <strong>${comment.username}</strong>
    819819        at ${comment.time.strftime('%x %X')}
     
    919919== Advanced Topics ==
    920920
     921=== Adding an Atom Feed ===
     922
     923Every web site needs an RSS or [http://www.atomenabled.org/ Atom] feed these days. So we shall provide one too.
     924
     925Adding Atom feeds to Geddit is fairly straightforward. First, we'll need to add auto-discovery links to the index and detail pages.
     926
     927Inside the `<head>` element of `geddit/templates/index.html`, add:
     928
     929{{{
     930#!genshi
     931    <link rel="alternate" type="application/atom+xml" title="Geddit News"
     932          href="${url('/feed/')}" />
     933}}}
     934
     935And inside the `<head>` element of `geddit/templates/info.html`, add:
     936
     937{{{
     938#!genshi
     939    <link rel="alternate" type="application/atom+xml" title="Geddit: ${link.title}"
     940          href="${url('/feed/%s/' % link.id)}" />
     941}}}
     942
     943Now we need to add the `feed()` method to our `Root` class in `geddit/controller.py`:
     944
     945{{{
     946#!python
     947    @cherrypy.expose
     948    @template.output('index.xml', method='xml')
     949    def feed(self, id=None):
     950        if id:
     951            link = self.data.get(id)
     952            if not link:
     953                raise cherrypy.NotFound()
     954            return template.render('info.xml', link=link)
     955        else:
     956            links = sorted(self.data.values(), key=operator.attrgetter('time'))
     957            return template.render(links=links)
     958}}}
     959
     960Note that this method dispatches to different templates depending on whether the `id` parameter was provided. So, for the URL `/feed/`, we'll render the list of links using the template `index.xml`, and for the URL `/feed/{link_id}/`, we'll render a link and a list of related comments using the template `info.xml`.
     961
     962The templates for this are also pretty simple. First, `geddit/templates/index.xml`:
     963
     964{{{
     965#!genshi
     966<?xml version="1.0" encoding="utf-8"?>
     967<feed xmlns="http://www.w3.org/2005/Atom"
     968      xmlns:py="http://genshi.edgewall.org/">
     969
     970  <title>Geddit News</title>
     971  <id href="${url('/')}"/>
     972  <link rel="alternate" href="${url('/')}" type="text/html"/>
     973  <link rel="self" href="${url('/feed/')}" type="application/atom+xml"/>
     974  <updated>${links[0].time.isoformat()}</updated>
     975
     976  <entry py:for="link in reversed(links)">
     977    <title>${link.url}</title>
     978    <link rel="alternate" href="${link.url}" type="text/html"/>
     979    <id>${url('/info/%s/' % link.id)}</id>
     980    <author>
     981      <name>${link.username}</name>
     982    </author>
     983    <updated>${link.time.isoformat()}</updated>
     984    <summary>${link.title}</summary>
     985  </entry>
     986
     987</feed>
     988}}}
     989
     990And now, `geddit/templates/info.xml`:
     991
     992{{{
     993#!genshi
     994<?xml version="1.0" encoding="utf-8"?>
     995<feed xmlns="http://www.w3.org/2005/Atom"
     996      xmlns:py="http://genshi.edgewall.org/">
     997
     998  <title>Geddit: ${link.title}</title>
     999  <id href="${url('/info/%s/' % link.id)}"/>
     1000  <link rel="alternate" href="${url('/info/%s/' % link.id)}" type="text/html"/>
     1001  <link rel="self" href="${url('/feed/%s/' % link.id)}" type="application/atom+xml"/>
     1002  <updated py:with="time=link.comments and link.comments)[-1].time or link.time">
     1003    ${time.isoformat()}
     1004  </updated>
     1005
     1006  <entry py:for="idx, comment in enumerate(reversed(link.comments))">
     1007    <title>Comment ${len(link.comments) - idx} on “${link.title}”</title>
     1008    <link rel="alternate" href="${url('/info/%s/' % link.id)}#comment${idx}"
     1009          type="text/html"/>
     1010    <id>${url('/info/%s/' % link.id)}#comment${idx}</id>
     1011    <author>
     1012      <name>${comment.username}</name>
     1013    </author>
     1014    <updated>${comment.time.isoformat()}</updated>
     1015    <summary>${comment.content}</summary>
     1016  </entry>
     1017
     1018</feed>
     1019}}}
     1020
     1021Voila! We now provide Atom feeds for all our content.
     1022
     1023[[Image(tutorial05.png)]]
     1024
    9211025=== Allowing Markup in Comments ===
    9221026
     
    9301034'''TODO'''
    9311035
    932 === Adding an Atom Feed ===
    933 
    934 '''TODO'''
    935 
    9361036== Summary ==
    9371037