| 921 | === Adding an Atom Feed === |
| 922 | |
| 923 | Every web site needs an RSS or [http://www.atomenabled.org/ Atom] feed these days. So we shall provide one too. |
| 924 | |
| 925 | Adding Atom feeds to Geddit is fairly straightforward. First, we'll need to add auto-discovery links to the index and detail pages. |
| 926 | |
| 927 | Inside 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 | |
| 935 | And 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 | |
| 943 | Now 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 | |
| 960 | Note 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 | |
| 962 | The 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 | |
| 990 | And 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 | |
| 1021 | Voila! We now provide Atom feeds for all our content. |
| 1022 | |
| 1023 | [[Image(tutorial05.png)]] |
| 1024 | |