Skip to content

Commit 43b4920

Browse files
committed
Support feed discovery and enumeration
This adds support for a Jinja function/filter, “atom_feeds”, which can be used to enumerate all feeds defined in the project (“atom_feeds()”), or those relevant to the page being generated (“atom_feeds(for_page=this)”). This is convenient, e.g., to define a generic site header which automatically displays a “subscribe” link on those pages which generate feeds.
1 parent e233486 commit 43b4920

File tree

5 files changed

+97
-0
lines changed

5 files changed

+97
-0
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,18 @@ Link to the feed in a template like this:
100100
{{ 'blog@atom/main'|url }}
101101
```
102102

103+
The plugin also defines a function to enumerate all feeds or a subset of feeds
104+
relevant to the current page.
105+
106+
```
107+
{% for feed in atom_feeds(for_page=this) %}
108+
{{ feed | url }}
109+
{% endfor %}
110+
```
111+
112+
When the argument `for_page` is omitted, the function will enumerate all feeds
113+
defined in your project.
114+
103115
# Changes
104116

105117
2016-06-02: Version 0.2. Python 3 compatibility (thanks to Dan Bauman),

lektor_atom.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,9 @@ def get_atom_config(self, feed_id, key):
184184
def on_setup_env(self, **extra):
185185
self.env.add_build_program(AtomFeedSource, AtomFeedBuilderProgram)
186186

187+
self.env.jinja_env.filters['atom_feeds'] = self.atom_feeds
188+
self.env.jinja_env.globals['atom_feeds'] = self.atom_feeds
189+
187190
@self.env.virtualpathresolver('atom')
188191
def feed_path_resolver(node, pieces):
189192
if len(pieces) != 1:
@@ -204,3 +207,33 @@ def generate_feeds(source):
204207
for _id in self.get_config().sections():
205208
if source.path == self.get_atom_config(_id, 'source_path'):
206209
yield AtomFeedSource(source, _id, self)
210+
211+
def _all_feeds(self):
212+
ctx = get_ctx()
213+
214+
feeds = []
215+
for feed_id in self.get_config().sections():
216+
path = self.get_atom_config(feed_id, 'source_path')
217+
feed = ctx.pad.get('%s@atom/%s' % (path, feed_id))
218+
if feed:
219+
feeds.append(feed)
220+
221+
return feeds
222+
223+
def _feeds_for(self, page):
224+
ctx = get_ctx()
225+
record = page.record
226+
227+
feeds = []
228+
for section in self.get_config().sections():
229+
feed = ctx.pad.get('%s@atom/%s' % (record.path, section))
230+
if feed:
231+
feeds.append(feed)
232+
233+
return feeds
234+
235+
def atom_feeds(self, for_page=None):
236+
if not for_page:
237+
return self._all_feeds()
238+
else:
239+
return self._feeds_for(for_page)

tests/demo-project/configs/atom.ini

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,13 @@ item_body_field = contents
1717
item_author_field = writer
1818
item_date_field = published
1919
item_model = custom-blog-post
20+
21+
[feed-four]
22+
name = Feed Three (uncensored)
23+
source_path = /custom-blog
24+
filename = nsfw.xml
25+
item_title_field = headline
26+
item_body_field = contents
27+
item_author_field = writer
28+
item_date_field = published
29+
item_model = custom-blog-post
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
_model: page
2+
---
3+
contents: Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo (cf. Wikipedia)

tests/test_lektor_atom.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22

3+
from lektor.context import Context
34
from lxml import objectify
45

56

@@ -113,3 +114,41 @@ def test_dependencies(pad, builder, reporter):
113114
'configs/atom.ini',
114115
])
115116

117+
118+
def feeds_from_template(pad, template):
119+
with Context(pad=pad):
120+
return set(
121+
pad.env.jinja_env.from_string(template)
122+
.render()
123+
.split()
124+
)
125+
126+
127+
def test_discover_all(pad):
128+
template = r'''
129+
{% for feed in atom_feeds() %}
130+
{{ feed.feed_id }}
131+
{% endfor %}
132+
'''
133+
all_feeds = set(['feed-one', 'feed-two',
134+
'feed-three', 'feed-four'])
135+
feeds_discovered = feeds_from_template(pad, template)
136+
assert feeds_discovered == all_feeds
137+
138+
139+
def test_discover_local(pad):
140+
template_blog = r'''
141+
{% for feed in atom_feeds(for_page=site.get('/custom-blog')) %}
142+
{{ feed.feed_id }}
143+
{% endfor %}
144+
'''
145+
feeds_blog = feeds_from_template(pad, template_blog)
146+
assert feeds_blog == set(['feed-three', 'feed-four'])
147+
148+
template_noblog = r'''
149+
{% for feed in atom_feeds(for_page=site.get('/no-feed-content')) %}
150+
{{ feed.feed_id }}
151+
{% endfor %}
152+
'''
153+
feeds_noblog = feeds_from_template(pad, template_noblog)
154+
assert len(feeds_noblog) == 0

0 commit comments

Comments
 (0)