Skip to content

Commit

Permalink
Support feed discovery and enumeration
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
eigengrau authored and jcharaoui committed Oct 20, 2021
1 parent e26694f commit 862a116
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 1 deletion.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,22 @@ Link to the feed in a template like this:
```
{{ '/blog@atom/main'|url }}
```

The plugin also defines a function to enumerate all feeds or a subset of feeds
relevant to the current page.

```
{% for feed in atom_feeds(for_page=this) %}
{{ feed | url }}
{% endfor %}
```

When the argument `for_page` is omitted, the function will enumerate all feeds
defined in your project.

# Changes

2016-06-02: Version 0.2. Python 3 compatibility (thanks to Dan Bauman),
colored error output during build, fix for Markdown-formatted item subtitles.

2016-01-09: Version 0.1, initial release.
35 changes: 34 additions & 1 deletion lektor_atom.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,10 @@ def get_atom_config(self, feed_id, key):
def on_setup_env(self, **extra):
self.env.add_build_program(AtomFeedSource, AtomFeedBuilderProgram)

@self.env.virtualpathresolver("atom")
self.env.jinja_env.filters['atom_feeds'] = self.atom_feeds
self.env.jinja_env.globals['atom_feeds'] = self.atom_feeds

@self.env.virtualpathresolver('atom')
def feed_path_resolver(node, pieces):
if len(pieces) != 1:
return
Expand All @@ -206,3 +209,33 @@ def generate_feeds(source):
for _id in self.get_config().sections():
if source.path == self.get_atom_config(_id, "source_path"):
yield AtomFeedSource(source, _id, self)

def _all_feeds(self):
ctx = get_ctx()

feeds = []
for feed_id in self.get_config().sections():
path = self.get_atom_config(feed_id, 'source_path')
feed = ctx.pad.get('%s@atom/%s' % (path, feed_id))
if feed:
feeds.append(feed)

return feeds

def _feeds_for(self, page):
ctx = get_ctx()
record = page.record

feeds = []
for section in self.get_config().sections():
feed = ctx.pad.get('%s@atom/%s' % (record.path, section))
if feed:
feeds.append(feed)

return feeds

def atom_feeds(self, for_page=None):
if not for_page:
return self._all_feeds()
else:
return self._feeds_for(for_page)
10 changes: 10 additions & 0 deletions tests/demo-project/configs/atom.ini
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,13 @@ item_body_field = contents
item_author_field = writer
item_date_field = published
item_model = custom-blog-post

[feed-four]
name = Feed Three (uncensored)
source_path = /custom-blog
filename = nsfw.xml
item_title_field = headline
item_body_field = contents
item_author_field = writer
item_date_field = published
item_model = custom-blog-post
3 changes: 3 additions & 0 deletions tests/demo-project/content/no-feed-content/contents.lr
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
_model: page
---
contents: Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo (cf. Wikipedia)
39 changes: 39 additions & 0 deletions tests/test_lektor_atom.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os

from lektor.context import Context
from lxml import objectify

try:
Expand Down Expand Up @@ -129,3 +130,41 @@ def test_dependencies(pad, builder, reporter):
"configs/atom.ini",
]
)

def feeds_from_template(pad, template):
with Context(pad=pad):
return set(
pad.env.jinja_env.from_string(template)
.render()
.split()
)


def test_discover_all(pad):
template = r'''
{% for feed in atom_feeds() %}
{{ feed.feed_id }}
{% endfor %}
'''
all_feeds = set(['feed-one', 'feed-two',
'feed-three', 'feed-four'])
feeds_discovered = feeds_from_template(pad, template)
assert feeds_discovered == all_feeds


def test_discover_local(pad):
template_blog = r'''
{% for feed in atom_feeds(for_page=site.get('/custom-blog')) %}
{{ feed.feed_id }}
{% endfor %}
'''
feeds_blog = feeds_from_template(pad, template_blog)
assert feeds_blog == set(['feed-three', 'feed-four'])

template_noblog = r'''
{% for feed in atom_feeds(for_page=site.get('/no-feed-content')) %}
{{ feed.feed_id }}
{% endfor %}
'''
feeds_noblog = feeds_from_template(pad, template_noblog)
assert len(feeds_noblog) == 0

0 comments on commit 862a116

Please sign in to comment.