Provides Custom URLs for FEEDS

Provides an optional FEED URL. Feed variables have been split into two, _SAVE_AS and _URL.

 _SAVE_AS variables are used to define the RSS/ATOM Files.
 _URL variables are the feed slugs (aligns to post/page variables)

 Using rewrite rules (nginx/apache) it is now possible to have _pretty_ feed URLS like /feed or /feed/tag/pelican
This commit is contained in:
Nick 2015-01-05 10:14:59 +00:00
commit 7f8df5bb8e
12 changed files with 223 additions and 131 deletions

View file

@ -154,11 +154,11 @@ To disable feed generation, all feed settings should be set to ``None``.
All but three feed settings already default to ``None``, so if you want to
disable all feed generation, you only need to specify the following settings::
FEED_ALL_ATOM = None
CATEGORY_FEED_ATOM = None
TRANSLATION_FEED_ATOM = None
AUTHOR_FEED_ATOM = None
AUTHOR_FEED_RSS = None
FEED_ALL_ATOM_SAVE_AS = None
CATEGORY_FEED_ATOM_SAVE_AS = None
TRANSLATION_FEED_ATOM_SAVE_AS = None
AUTHOR_FEED_ATOM_SAVE_AS = None
AUTHOR_FEED_RSS_SAVE_AS = None
The word ``None`` should not be surrounded by quotes. Please note that ``None``
and ``''`` are not the same thing.
@ -192,6 +192,24 @@ generates ``'feeds/all.atom.xml'`` by default and ``FEED_ATOM`` now defaults to
TRANSLATION_FEED -> TRANSLATION_FEED_ATOM
Starting in 3.5, the feed variables have been split into two. FEED_ATOM
has now become FEED_ATOM_SAVE_AS allowing FEED_ATOM_URL to be introduced; FEED_ATOM_URL
allows you to assign URL Slugs to feeds such as /feed/atom. (URL rewriting will still
be required on the web server). Here is an exact list of the renamed settings::
FEED_ATOM -> FEED_ATOM_SAVE_AS
FEED_RSS -> FEED_RSS_SAVE_AS
FEED_ALL_ATOM -> FEED_ALL_ATOM_SAVE_AS
FEED_ALL_RSS -> FEED_ALL_RSS_SAVE_AS
CATEGORY_FEED_ATOM -> CATEGORY_FEED_ATOM_SAVE_AS
CATEGORY_FEED_RSS -> CATEGORY_FEED_RSS_SAVE_AS
AUTHOR_FEED_ATOM -> AUTHOR_FEED_ATOM_SAVE_AS
AUTHOR_FEED_RSS -> AUTHOR_FEED_RSS_SAVE_AS
TAG_FEED_ATOM -> TAG_FEED_ATOM_SAVE_AS
TAG_FEED_RSS -> TAG_FEED_RSS_SAVE_AS
To use the new URLs see :doc:`feed settings <settings>`.
Older themes that referenced the old setting names may not link properly.
In order to rectify this, please update your theme for compatibility by changing
the relevant values in your template files. For an example of complete feed

View file

@ -518,39 +518,50 @@ feeds if you prefer.
Pelican generates category feeds as well as feeds for all your articles. It does
not generate feeds for tags by default, but it is possible to do so using
the ``TAG_FEED_ATOM`` and ``TAG_FEED_RSS`` settings:
the ``TAG_FEED_ATOM_SAVE_AS`` and ``TAG_FEED_RSS_SAVE_AS`` settings:
================================================= =====================================================
Setting name (followed by default value, if any) What does it do?
================================================= =====================================================
``FEED_DOMAIN = None``, i.e. base URL is "/" The domain prepended to feed URLs. Since feed URLs
should always be absolute, it is highly recommended
to define this (e.g., "http://feeds.example.com"). If
you have already explicitly defined SITEURL (see
above) and want to use the same domain for your
feeds, you can just set: ``FEED_DOMAIN = SITEURL``.
``FEED_ATOM = None``, i.e. no Atom feed Relative URL to output the Atom feed.
``FEED_RSS = None``, i.e. no RSS Relative URL to output the RSS feed.
``FEED_ALL_ATOM = 'feeds/all.atom.xml'`` Relative URL to output the all-posts Atom feed:
this feed will contain all posts regardless of their
language.
``FEED_ALL_RSS = None``, i.e. no all-posts RSS Relative URL to output the all-posts RSS feed:
this feed will contain all posts regardless of their
language.
``CATEGORY_FEED_ATOM = 'feeds/%s.atom.xml'`` [2]_ Where to put the category Atom feeds.
``CATEGORY_FEED_RSS = None``, i.e. no RSS Where to put the category RSS feeds.
``AUTHOR_FEED_ATOM = 'feeds/%s.atom.xml'`` [2]_ Where to put the author Atom feeds.
``AUTHOR_FEED_RSS = 'feeds/%s.rss.xml'`` [2]_ Where to put the author RSS feeds.
``TAG_FEED_ATOM = None``, i.e. no tag feed Relative URL to output the tag Atom feed. It should
be defined using a "%s" match in the tag name.
``TAG_FEED_RSS = None``, i.e. no RSS tag feed Relative URL to output the tag RSS feed
``FEED_MAX_ITEMS`` Maximum number of items allowed in a feed. Feed item
quantity is unrestricted by default.
================================================= =====================================================
========================================================= =====================================================
Setting name (followed by default value, if any) What does it do?
========================================================= =====================================================
``FEED_DOMAIN = None``, i.e. base URL is "/" The domain prepended to feed URLs. Since feed URLs
should always be absolute, it is highly recommended
to define this (e.g., "http://feeds.example.com"). If
you have already explicitly defined SITEURL (see
above) and want to use the same domain for your
feeds, you can just set: ``FEED_DOMAIN = SITEURL``.
``FEED_ATOM_SAVE_AS = None``, i.e. no Atom feed Path to output the Atom feed.
``FEED_ATOM_URL = None``, i.e. no Atom Slug Relative URL (Slug) for the Atom feed.
``FEED_RSS_SAVE_AS = None``, i.e. no RSS Path to output the RSS feed.
``FEED_RSS_URL = None``, i.e. no RSS Slug Relative URL (Slug) for the RSS feed.
``FEED_ALL_ATOM_SAVE_AS = 'feeds/all.atom.xml'`` Path to output the all-posts Atom feed:
this feed will contain all posts regardless of their
language.
``FEED_ALL_ATOM_URL = None``, i.e. no all Atom Slug Relative URL to the all-posts Atom feed.
``FEED_ALL_RSS_SAVE_AS = None``, i.e. no all-posts RSS Relative URL to output the all-posts RSS feed:
this feed will contain all posts regardless of their
language.
``FEED_ALL_RSS_URL = None``, i.e. no all RSS Slug Relative URL to the all-posts RSS feed.
``CATEGORY_FEED_ATOM_SAVE_AS = 'feeds/%s.atom.xml'`` [2]_ Path to put the category Atom feeds.
``CATEGORY_FEED_ATOM_URL = None`` Relative URL to the category Atom feed. [4]_
``CATEGORY_FEED_RSS_SAVE_AS = None``, i.e. no RSS Path to put the category RSS feeds.
``CATEGORY_FEED_RSS_URL = None`` Relative URL for the category RSS feeds. [4]_
``AUTHOR_FEED_ATOM_SAVE_AS = 'feeds/%s.atom.xml'`` [2]_ Path to put the author Atom feeds.
``AUTHOR_FEED_ATOM_URL = None`` Relative URL for the authoor atom feeds. [4]_
``AUTHOR_FEED_RSS_SAVE_AS = 'feeds/%s.rss.xml'`` [2]_ Path to put the author RSS feeds.
``AUTHOR_FEED_RSS_URL = None`` Relative URL for the author RSS feeds. [4]_
``TAG_FEED_ATOM_SAVE_AS = None``, i.e. no tag feed Path to output the tag Atom feed. It should
be defined using a "%s" match in the tag name.
``TAG_FEED_ATOM_URL = None`` Relative URL for the tag atom feeds. [4]_
``TAG_FEED_RSS_SAVE_AS = None``, i.e. no RSS tag feed Path to output the tag RSS feed
``TAG_FEED_RSS_URL = None`` Relative URL for the tag RSS feeds. [4]_
``FEED_MAX_ITEMS`` Maximum number of items allowed in a feed. Feed item
quantity is unrestricted by default.
========================================================= =====================================================
If you don't want to generate some or any of these feeds, set the above variables to ``None``.
.. [2] %s is the name of the category.
.. [4] %s should be used for substitution, e.g. "feeds/atom/category/%s"
FeedBurner

View file

@ -334,20 +334,34 @@ Feeds
The feed variables changed in 3.0. Each variable now explicitly lists ATOM or
RSS in the name. ATOM is still the default. Old themes will need to be updated.
If you use URL rewriting on your webserver slugs can be setup for feeds.
Here is a complete list of the feed variables::
FEED_ATOM
FEED_RSS
FEED_ALL_ATOM
FEED_ALL_RSS
CATEGORY_FEED_ATOM
CATEGORY_FEED_RSS
AUTHOR_FEED_ATOM
AUTHOR_FEED_RSS
TAG_FEED_ATOM
TAG_FEED_RSS
TRANSLATION_FEED_ATOM
TRANSLATION_FEED_RSS
FEED_ATOM_SAVE_AS
FEED_RSS_SAVE_AS
FEED_ALL_ATOM_SAVE_AS
FEED_ALL_RSS_SAVE_AS
CATEGORY_FEED_ATOM_SAVE_AS
CATEGORY_FEED_RSS_SAVE_AS
AUTHOR_FEED_ATOM_SAVE_AS
AUTHOR_FEED_RSS_SAVE_AS
TAG_FEED_ATOM_SAVE_AS
TAG_FEED_RSS_SAVE_AS
TRANSLATION_FEED_ATOM_SAVE_AS
TRANSLATION_FEED_RSS_SAVE_AS
FEED_ATOM_URL
FEED_RSS_URL
FEED_ALL_ATOM_URL
FEED_ALL_RSS_URL
CATEGORY_FEED_ATOM_URL
CATEGORY_FEED_RSS_URL
AUTHOR_FEED_ATOM_URL
AUTHOR_FEED_RSS_URL
TAG_FEED_ATOM_URL
TAG_FEED_RSS_URL
TRANSLATION_FEED_ATOM_URL
TRANSLATION_FEED_RSS_URL
Inheritance

View file

@ -128,7 +128,19 @@ class Pelican(object):
for new, old in [('FEED', 'FEED_ATOM'), ('TAG_FEED', 'TAG_FEED_ATOM'),
('CATEGORY_FEED', 'CATEGORY_FEED_ATOM'),
('TRANSLATION_FEED', 'TRANSLATION_FEED_ATOM')]:
('TRANSLATION_FEED', 'TRANSLATION_FEED_ATOM'),
('FEED_ATOM', 'FEED_ATOM_SAVE_AS'),
('FEED_RSS', 'FEED_RSS_SAVE_AS'),
('FEED_ALL_ATOM', 'FEED_ALL_ATOM_SAVE_AS'),
('FEED_ALL_RSS', 'FEED_ALL_RSS_SAVE_AS'),
('CATEGORY_FEED_ATOM', 'CATEGORY_FEED_ATOM_SAVE_AS'),
('CATEGORY_FEED_RSS', 'CATEGORY_FEED_RSS_SAVE_AS'),
('AUTHOR_FEED_ATOM', 'AUTHOR_FEED_ATOM_SAVE_AS'),
('AUTHOR_FEED_RSS', 'AUTHOR_FEED_RSS_SAVE_AS'),
('TAG_FEED_ATOM', 'TAG_FEED_ATOM_SAVE_AS'),
('TAG_FEED_RSS', 'TAG_FEED_RSS_SAVE_AS'),
('TRANSLATION_FEED_ATOM', 'TRANSLATION_FEED_ATOM_SAVE_AS'),
('TRANSLATION_FEED_RSS', 'TRANSLATION_FEED_RSS_SAVE_AS')]:
if self.settings.get(new, False):
logger.warning(
'Found deprecated `%(new)s` in settings. Modify %(new)s '
@ -146,7 +158,7 @@ class Pelican(object):
context = self.settings.copy()
# Share these among all the generators and content objects:
context['filenames'] = {} # maps source path to Content object or None
context['localsiteurl'] = self.settings['SITEURL']
context['localsiteurl'] = self.settings['SITEURL']
generators = [
cls(
@ -228,7 +240,7 @@ class Pelican(object):
logger.debug('Found writer: %s', writer)
else:
logger.warning(
'%s writers found, using only first one: %s',
'%s writers found, using only first one: %s',
writers_found, writer)
return writer(self.output_path, settings=self.settings)

View file

@ -264,85 +264,123 @@ class ArticlesGenerator(CachingGenerator):
def generate_feeds(self, writer):
"""Generate the feeds from the current context, and output files."""
if self.settings.get('FEED_ATOM'):
writer.write_feed(self.articles, self.context,
self.settings['FEED_ATOM'])
if self.settings.get('FEED_ATOM_SAVE_AS'):
if not self.settings.get('FEED_ATOM_URL'):
self.settings['FEED_ATOM_URL'] = self.settings.get('FEED_ATOM_SAVE_AS')
if self.settings.get('FEED_RSS'):
writer.write_feed(self.articles, self.context,
self.settings['FEED_RSS'], feed_type='rss')
path=self.settings['FEED_ATOM_SAVE_AS'], feed_slug=self.settings['FEED_ATOM_URL'])
if (self.settings.get('FEED_ALL_ATOM')
or self.settings.get('FEED_ALL_RSS')):
if self.settings.get('FEED_RSS_SAVE_AS'):
if not self.settings.get('FEED_RSS_URL'):
self.settings['FEED_RSS_URL'] = self.settings.get('FEED_RSS_SAVE_AS')
writer.write_feed(self.articles, self.context,
self.settings['FEED_RSS_SAVE_AS'], feed_type='rss', feed_slug=self.settings['FEED_RSS_URL'])
if (self.settings.get('FEED_ALL_ATOM_SAVE_AS')
or self.settings.get('FEED_ALL_RSS_SAVE_AS')):
all_articles = list(self.articles)
for article in self.articles:
all_articles.extend(article.translations)
all_articles.sort(key=attrgetter('date'), reverse=True)
if self.settings.get('FEED_ALL_ATOM'):
writer.write_feed(all_articles, self.context,
self.settings['FEED_ALL_ATOM'])
if self.settings.get('FEED_ALL_ATOM_SAVE_AS'):
if not self.settings.get('FEED_ALL_ATOM_URL'):
self.settings['FEED_ALL_ATOM_URL'] = self.settings.get('FEED_ALL_ATOM_SAVE_AS')
if self.settings.get('FEED_ALL_RSS'):
writer.write_feed(all_articles, self.context,
self.settings['FEED_ALL_RSS'],
feed_type='rss')
self.settings['FEED_ALL_ATOM_SAVE_AS'], feed_slug=self.settings['FEED_ALL_ATOM_URL'])
if self.settings.get('FEED_ALL_RSS_SAVE_AS'):
if not self.settings.get('FEED_ALL_RSS_URL'):
self.settings['FEED_ALL_RSS_URL'] = self.settings.get('FEED_ALL_RSS_SAVE_AS')
writer.write_feed(all_articles, self.context,
self.settings['FEED_ALL_RSS_SAVE_AS'],
feed_type='rss', feed_slug=self.settings['FEED_ALL_RSS_URL'])
for cat, arts in self.categories:
arts.sort(key=attrgetter('date'), reverse=True)
if self.settings.get('CATEGORY_FEED_ATOM'):
writer.write_feed(arts, self.context,
self.settings['CATEGORY_FEED_ATOM']
% cat.slug)
if self.settings.get('CATEGORY_FEED_ATOM_SAVE_AS'):
if not self.settings.get('CATEGORY_FEED_ATOM_URL'):
self.settings['CATEGORY_FEED_ATOM_URL'] = self.settings.get('CATEGORY_FEED_ATOM_SAVE_AS')
if self.settings.get('CATEGORY_FEED_RSS'):
writer.write_feed(arts, self.context,
self.settings['CATEGORY_FEED_RSS']
% cat.slug, feed_type='rss')
self.settings['CATEGORY_FEED_ATOM_SAVE_AS']
% cat.slug, feed_slug=self.settings['CATEGORY_FEED_ATOM_URL'] % cat.slug)
if self.settings.get('CATEGORY_FEED_RSS_SAVE_AS'):
if not self.settings.get('CATEGORY_FEED_RSS_URL'):
self.settings['CATEGORY_FEED_RSS_URL'] = self.settings.get('CATEGORY_FEED_RSS_SAVE_AS')
writer.write_feed(arts, self.context,
self.settings['CATEGORY_FEED_RSS_SAVE_AS']
% cat.slug, feed_type='rss', feed_slug=self.settings['CATEGORY_FEED_RSS_URL'] % cat.slug)
for auth, arts in self.authors:
arts.sort(key=attrgetter('date'), reverse=True)
if self.settings.get('AUTHOR_FEED_ATOM'):
writer.write_feed(arts, self.context,
self.settings['AUTHOR_FEED_ATOM']
% auth.slug)
if self.settings.get('AUTHOR_FEED_ATOM_SAVE_AS'):
if self.settings.get('AUTHOR_FEED_RSS'):
writer.write_feed(arts, self.context,
self.settings['AUTHOR_FEED_RSS']
% auth.slug, feed_type='rss')
if not self.settings.get('AUTHOR_FEED_ATOM_URL'):
self.settings['AUTHOR_FEED_ATOM_URL'] = self.settings.get('AUTHOR_FEED_ATOM_SAVE_AS')
if (self.settings.get('TAG_FEED_ATOM')
or self.settings.get('TAG_FEED_RSS')):
writer.write_feed(arts, self.context,
self.settings['AUTHOR_FEED_ATOM_SAVE_AS']
% auth.slug, feed_slug=self.settings['AUTHOR_FEED_ATOM_URL'] % auth.slug)
if self.settings.get('AUTHOR_FEED_RSS_SAVE_AS'):
if not self.settings.get('AUTHOR_FEED_RSS_URL'):
self.settings['AUTHOR_FEED_RSS_URL'] = self.settings.get('AUTHOR_FEED_RSS_SAVE_AS')
writer.write_feed(arts, self.context,
self.settings['AUTHOR_FEED_RSS_SAVE_AS']
% auth.slug, feed_type='rss', feed_slug=self.settings['AUTHOR_FEED_RSS_URL'] % auth.slug)
if (self.settings.get('TAG_FEED_ATOM_SAVE_AS')
or self.settings.get('TAG_FEED_RSS_SAVE_AS')):
for tag, arts in self.tags.items():
arts.sort(key=attrgetter('date'), reverse=True)
if self.settings.get('TAG_FEED_ATOM'):
writer.write_feed(arts, self.context,
self.settings['TAG_FEED_ATOM']
% tag.slug)
if self.settings.get('TAG_FEED_ATOM_SAVE_AS'):
if not self.settings.get('TAG_FEED_ATOM_URL'):
self.settings['TAG_FEED_ATOM_URL'] = self.settings.get('TAG_FEED_ATOM_SAVE_AS')
if self.settings.get('TAG_FEED_RSS'):
writer.write_feed(arts, self.context,
self.settings['TAG_FEED_RSS'] % tag.slug,
feed_type='rss')
self.settings['TAG_FEED_ATOM_SAVE_AS']
% tag.slug, feed_slug=self.settings['TAG_FEED_ATOM_URL'] % tag.slug)
if (self.settings.get('TRANSLATION_FEED_ATOM')
or self.settings.get('TRANSLATION_FEED_RSS')):
if self.settings.get('TAG_FEED_RSS_SAVE_AS'):
if not self.settings.get('TAG_FEED_RSS_URL'):
self.settings['TAG_FEED_RSS_URL'] = self.settings.get('TAG_FEED_RSS_SAVE_AS')
writer.write_feed(arts, self.context,
self.settings['TAG_FEED_RSS_SAVE_AS'] % tag.slug,
feed_type='rss', feed_slug=self.settings['TAG_FEED_RSS_URL'] % tag.slug)
if (self.settings.get('TRANSLATION_FEED_ATOM_SAVE_AS')
or self.settings.get('TRANSLATION_FEED_RSS_SAVE_AS')):
translations_feeds = defaultdict(list)
for article in chain(self.articles, self.translations):
translations_feeds[article.lang].append(article)
for lang, items in translations_feeds.items():
items.sort(key=attrgetter('date'), reverse=True)
if self.settings.get('TRANSLATION_FEED_ATOM'):
if self.settings.get('TRANSLATION_FEED_ATOM_SAVE_AS'):
if not self.settings.get('TRANSLATION_FEED_ATOM_URL'):
self.settings['TRANSLATION_FEED_ATOM_URL'] = self.settings.get('TRANSLATION_FEED_ATOM_SAVE_AS')
writer.write_feed(
items, self.context,
self.settings['TRANSLATION_FEED_ATOM'] % lang)
if self.settings.get('TRANSLATION_FEED_RSS'):
self.settings['TRANSLATION_FEED_ATOM_SAVE_AS'] % lang, feed_slug=self.settings['TRANSLATION_FEED_ATOM_URL'] % lang)
if self.settings.get('TRANSLATION_FEED_RSS_SAVE_AS'):
if not self.settings.get('TRANSLATION_FEED_RSS_URL'):
self.settings['TRANSLATION_FEED_RSS_URL'] = self.settings.get('TRANSLATION_FEED_RSS_SAVE_AS')
writer.write_feed(
items, self.context,
self.settings['TRANSLATION_FEED_RSS'] % lang,
feed_type='rss')
self.settings['TRANSLATION_FEED_RSS_SAVE_AS'] % lang,
feed_type='rss', feed_slug=self.settings['TRANSLATION_FEED_RSS_URL'] % lang)
def generate_articles(self, write):
"""Generate the articles."""

View file

@ -41,11 +41,11 @@ DEFAULT_CONFIG = {
'STATIC_EXCLUDE_SOURCES': True,
'THEME_STATIC_DIR': 'theme',
'THEME_STATIC_PATHS': ['static', ],
'FEED_ALL_ATOM': os.path.join('feeds', 'all.atom.xml'),
'CATEGORY_FEED_ATOM': os.path.join('feeds', '%s.atom.xml'),
'AUTHOR_FEED_ATOM': os.path.join('feeds', '%s.atom.xml'),
'AUTHOR_FEED_RSS': os.path.join('feeds', '%s.rss.xml'),
'TRANSLATION_FEED_ATOM': os.path.join('feeds', 'all-%s.atom.xml'),
'FEED_ALL_ATOM_SAVE_AS': os.path.join('feeds', 'all.atom.xml'),
'CATEGORY_FEED_ATOM_SAVE_AS': os.path.join('feeds', '%s.atom.xml'),
'AUTHOR_FEED_ATOM_SAVE_AS': os.path.join('feeds', '%s.atom.xml'),
'AUTHOR_FEED_RSS_SAVE_AS': os.path.join('feeds', '%s.rss.xml'),
'TRANSLATION_FEED_ATOM_SAVE_AS': os.path.join('feeds', 'all-%s.atom.xml'),
'FEED_MAX_ITEMS': '',
'SITEURL': '',
'SITENAME': 'A Pelican Blog',
@ -284,12 +284,12 @@ def configure_settings(settings):
# Warn if feeds are generated with both SITEURL & FEED_DOMAIN undefined
feed_keys = [
'FEED_ATOM', 'FEED_RSS',
'FEED_ALL_ATOM', 'FEED_ALL_RSS',
'CATEGORY_FEED_ATOM', 'CATEGORY_FEED_RSS',
'AUTHOR_FEED_ATOM', 'AUTHOR_FEED_RSS',
'TAG_FEED_ATOM', 'TAG_FEED_RSS',
'TRANSLATION_FEED_ATOM', 'TRANSLATION_FEED_RSS',
'FEED_ATOM_SAVE_AS', 'FEED_RSS_SAVE_AS',
'FEED_ALL_ATOM_SAVE_AS', 'FEED_ALL_RSS_SAVE_AS',
'CATEGORY_FEED_ATOM_SAVE_AS', 'CATEGORY_FEED_RSS_SAVE_AS',
'AUTHOR_FEED_ATOM_SAVE_AS', 'AUTHOR_FEED_RSS_SAVE_AS',
'TAG_FEED_ATOM_SAVE_AS', 'TAG_FEED_RSS_SAVE_AS',
'TRANSLATION_FEED_ATOM_SAVE_AS', 'TRANSLATION_FEED_RSS_SAVE_AS',
]
if any(settings.get(k) for k in feed_keys):

View file

@ -11,8 +11,8 @@ PDF_GENERATOR = False
REVERSE_CATEGORY_ORDER = True
DEFAULT_PAGINATION = 2
FEED_RSS = 'feeds/all.rss.xml'
CATEGORY_FEED_RSS = 'feeds/%s.rss.xml'
FEED_RSS_SAVE_AS = 'feeds/all.rss.xml'
CATEGORY_FEED_RSS_SAVE_AS = 'feeds/%s.rss.xml'
LINKS = (('Biologeek', 'http://biologeek.org'),
('Filyb', "http://filyb.info/"),

View file

@ -110,10 +110,10 @@ class TestArticlesGenerator(unittest.TestCase):
writer = MagicMock()
generator.generate_feeds(writer)
writer.write_feed.assert_called_with([], settings,
'feeds/all.atom.xml')
'feeds/all.atom.xml', feed_slug='feeds/all.atom.xml')
generator = ArticlesGenerator(
context=settings, settings=get_settings(FEED_ALL_ATOM=None),
context=settings, settings=get_settings(FEED_ALL_ATOM_SAVE_AS=None),
path=None, theme=settings['THEME'], output_path=None)
writer = MagicMock()
generator.generate_feeds(writer)
@ -678,4 +678,3 @@ class TestStaticGenerator(unittest.TestCase):
self.assertTrue(any(name.endswith(".md") for name in staticnames),
"STATIC_EXCLUDE_SOURCES=False failed to include a markdown file")

View file

@ -4,11 +4,11 @@
<meta charset="utf-8" />
<title>{% block title %}{{ SITENAME }}{%endblock%}</title>
<link rel="stylesheet" href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/css/{{ CSS_FILE }}" />
{% if FEED_ALL_ATOM %}
<link href="{{ FEED_DOMAIN }}/{{ FEED_ALL_ATOM }}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} Atom Feed" />
{% if FEED_ALL_ATOM_SAVE_AS %}
<link href="{{ FEED_DOMAIN }}/{{ FEED_ALL_ATOM_SAVE_AS }}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} Atom Feed" />
{% endif %}
{% if FEED_ALL_RSS %}
<link href="{{ FEED_DOMAIN }}/{{ FEED_ALL_RSS }}" type="application/rss+xml" rel="alternate" title="{{ SITENAME }} RSS Feed" />
{% if FEED_ALL_RSS_SAVE_AS %}
<link href="{{ FEED_DOMAIN }}/{{ FEED_ALL_RSS_SAVE_AS }}" type="application/rss+xml" rel="alternate" title="{{ SITENAME }} RSS Feed" />
{% endif %}
<!--[if IE]>
@ -49,15 +49,15 @@
</ul>
</div><!-- /.blogroll -->
{% endif %}
{% if SOCIAL or FEED_ALL_ATOM or FEED_ALL_RSS %}
{% if SOCIAL or FEED_ALL_ATOM_SAVE_AS or FEED_ALL_RSS_SAVE_AS %}
<div class="social">
<h2>social</h2>
<ul>
{% if FEED_ALL_ATOM %}
<li><a href="{{ FEED_DOMAIN }}/{{ FEED_ALL_ATOM }}" type="application/atom+xml" rel="alternate">atom feed</a></li>
{% if FEED_ALL_ATOM_SAVE_AS %}
<li><a href="{{ FEED_DOMAIN }}/{{ FEED_ALL_ATOM_SAVE_AS }}" type="application/atom+xml" rel="alternate">atom feed</a></li>
{% endif %}
{% if FEED_ALL_RSS %}
<li><a href="{{ FEED_DOMAIN }}/{{ FEED_ALL_RSS }}" type="application/rss+xml" rel="alternate">rss feed</a></li>
{% if FEED_ALL_RSS_SAVE_AS %}
<li><a href="{{ FEED_DOMAIN }}/{{ FEED_ALL_RSS_SAVE_AS }}" type="application/rss+xml" rel="alternate">rss feed</a></li>
{% endif %}
{% for name, link in SOCIAL %}

View file

@ -4,29 +4,29 @@
{% block head %}
<title>{% block title %}{{ SITENAME }}{% endblock title %}</title>
<meta charset="utf-8" />
{% if FEED_ALL_ATOM %}
<link href="{{ FEED_DOMAIN }}/{{ FEED_ALL_ATOM }}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} Full Atom Feed" />
{% if FEED_ALL_ATOM_SAVE_AS %}
<link href="{{ FEED_DOMAIN }}/{{ FEED_ALL_ATOM_SAVE_AS }}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} Full Atom Feed" />
{% endif %}
{% if FEED_ALL_RSS %}
<link href="{{ FEED_DOMAIN }}/{{ FEED_ALL_RSS }}" type="application/rss+xml" rel="alternate" title="{{ SITENAME }} Full RSS Feed" />
{% if FEED_ALL_RSS_SAVE_AS %}
<link href="{{ FEED_DOMAIN }}/{{ FEED_ALL_RSS_SAVE_AS }}" type="application/rss+xml" rel="alternate" title="{{ SITENAME }} Full RSS Feed" />
{% endif %}
{% if FEED_ATOM %}
<link href="{{ FEED_DOMAIN }}/{{ FEED_ATOM }}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} Atom Feed" />
{% if FEED_ATOM_SAVE_AS %}
<link href="{{ FEED_DOMAIN }}/{{ FEED_ATOM_SAVE_AS }}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} Atom Feed" />
{% endif %}
{% if FEED_RSS %}
<link href="{{ FEED_DOMAIN }}/{{ FEED_RSS }}" type="application/rss+xml" rel="alternate" title="{{ SITENAME }} RSS Feed" />
{% if FEED_RSS_SAVE_AS %}
<link href="{{ FEED_DOMAIN }}/{{ FEED_RSS_SAVE_AS }}" type="application/rss+xml" rel="alternate" title="{{ SITENAME }} RSS Feed" />
{% endif %}
{% if CATEGORY_FEED_ATOM and category %}
<link href="{{ FEED_DOMAIN }}/{{ CATEGORY_FEED_ATOM|format(category.slug) }}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} Categories Atom Feed" />
{% if CATEGORY_FEED_ATOM_SAVE_AS and category %}
<link href="{{ FEED_DOMAIN }}/{{ CATEGORY_FEED_ATOM_SAVE_AS|format(category.slug) }}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} Categories Atom Feed" />
{% endif %}
{% if CATEGORY_FEED_RSS and category %}
<link href="{{ FEED_DOMAIN }}/{{ CATEGORY_FEED_RSS|format(category.slug) }}" type="application/rss+xml" rel="alternate" title="{{ SITENAME }} Categories RSS Feed" />
{% if CATEGORY_FEED_RSS_SAVE_AS and category %}
<link href="{{ FEED_DOMAIN }}/{{ CATEGORY_FEED_RSS_SAVE_AS|format(category.slug) }}" type="application/rss+xml" rel="alternate" title="{{ SITENAME }} Categories RSS Feed" />
{% endif %}
{% if TAG_FEED_ATOM and tag %}
<link href="{{ FEED_DOMAIN }}/{{ TAG_FEED_ATOM|format(tag.slug) }}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} Tags Atom Feed" />
{% if TAG_FEED_ATOM_SAVE_AS and tag %}
<link href="{{ FEED_DOMAIN }}/{{ TAG_FEED_ATOM_SAVE_AS|format(tag.slug) }}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} Tags Atom Feed" />
{% endif %}
{% if TAG_FEED_RSS and tag %}
<link href="{{ FEED_DOMAIN }}/{{ TAG_FEED_RSS|format(tag.slug) }}" type="application/rss+xml" rel="alternate" title="{{ SITENAME }} Tags RSS Feed" />
{% if TAG_FEED_RSS_SAVE_AS and tag %}
<link href="{{ FEED_DOMAIN }}/{{ TAG_FEED_RSS_SAVE_AS|format(tag.slug) }}" type="application/rss+xml" rel="alternate" title="{{ SITENAME }} Tags RSS Feed" />
{% endif %}
{% endblock head %}
</head>

View file

@ -80,7 +80,7 @@ class Writer(object):
self._written_files.add(filename)
return open(filename, 'w', encoding=encoding)
def write_feed(self, elements, context, path=None, feed_type='atom'):
def write_feed(self, elements, context, path=None, feed_type='atom', feed_slug=None):
"""Generate a feed with the list of articles provided
Return the feed. If no path or output_path is specified, just
@ -98,7 +98,7 @@ class Writer(object):
'SITEURL', path_to_url(get_relative_path(path)))
self.feed_domain = context.get('FEED_DOMAIN')
self.feed_url = '{}/{}'.format(self.feed_domain, path)
self.feed_url = self.feed_domain + '/' + feed_slug
feed = self._create_new_feed(feed_type, context)

View file

@ -17,8 +17,8 @@ LOCALE = "C"
DEFAULT_PAGINATION = 4
DEFAULT_DATE = (2012, 3, 2, 14, 1, 1)
FEED_ALL_RSS = 'feeds/all.rss.xml'
CATEGORY_FEED_RSS = 'feeds/%s.rss.xml'
FEED_ALL_RSS_SAVE_AS = 'feeds/all.rss.xml'
CATEGORY_FEED_RSS_SAVE_AS = 'feeds/%s.rss.xml'
LINKS = (('Biologeek', 'http://biologeek.org'),
('Filyb', "http://filyb.info/"),