From 14fb307fa75b9746055d4c12f3657ee857b0b00a Mon Sep 17 00:00:00 2001 From: Bryan Brattlof Date: Thu, 10 Jan 2019 16:41:10 -0600 Subject: [PATCH] Add atom and rss feed url attributes to content objects --- docs/themes.rst | 6 +++ pelican/contents.py | 22 +++++++++ pelican/tests/test_contents.py | 46 ++++++++++++++++++ pelican/tests/test_urlwrappers.py | 58 +++++++++++++++++++++++ pelican/themes/simple/templates/base.html | 14 ++++-- pelican/urlwrappers.py | 16 +++++++ 6 files changed, 158 insertions(+), 4 deletions(-) diff --git a/docs/themes.rst b/docs/themes.rst index dcd72d75..a05d2f53 100644 --- a/docs/themes.rst +++ b/docs/themes.rst @@ -379,6 +379,8 @@ title Title of the article. translations List of translations :ref:`Article ` objects. url URL to the article page. +lang_atom_feed_url URL to the language's ATOM feed +land_rss_feed_url URL to the language's RSS feed ====================== =================================================== .. _PATH: settings.html#PATH @@ -399,6 +401,8 @@ page_name Author page name. save_as Location to save the author page. slug Page slug. url URL to the author page. +atom_feed_url URL to the ATOM feed for the author. +rss_feed_url URL to the RSS feed for the author. =================== =================================================== .. [1] for Author object, coming from `:authors:` or `AUTHOR`. @@ -438,6 +442,8 @@ title Title of the page. translations List of translations :ref:`Article ` objects. url URL to the page. +lang_atom_feed_url URL to the language's ATOM feed. +land_rss_feed_url URL to the language's RSS feed. ===================== =================================================== .. _PATH: settings.html#PATH diff --git a/pelican/contents.py b/pelican/contents.py index 235c814a..031ec054 100644 --- a/pelican/contents.py +++ b/pelican/contents.py @@ -93,6 +93,10 @@ class Content(object): self.in_default_lang = (self.lang == default_lang) + # build feed urls + self._build_rss_feed_url() + self._build_atom_feed_url() + # create the slug if not existing, generate slug according to # setting of SLUG_ATTRIBUTE if not hasattr(self, 'slug'): @@ -149,6 +153,24 @@ class Content(object): signals.content_object_init.send(self) + def _build_atom_feed_url(self): + atom_url = self.settings.get('TRANSLATION_FEED_ATOM', None) + if atom_url is None or getattr(self, 'lang', None) is None: + self.lang_atom_feed_url = None + else: + self.lang_atom_feed_url = atom_url.format( + lang=self.lang + ) + + def _build_rss_feed_url(self): + rss_url = self.settings.get('TRANSLATION_FEED_RSS', None) + if rss_url is None or getattr(self, 'lang', None) is None: + self.lang_rss_feed_url = None + else: + self.lang_rss_feed_url = rss_url.format( + lang=self.lang + ) + def __str__(self): return self.source_path or repr(self) diff --git a/pelican/tests/test_contents.py b/pelican/tests/test_contents.py index 104bc889..b51f68f7 100644 --- a/pelican/tests/test_contents.py +++ b/pelican/tests/test_contents.py @@ -133,6 +133,52 @@ class TestPage(LoggedTestCase): page = Page(**self.page_kwargs) self.assertEqual(page.lang, 'fr') + def test_lang_feed_urls(self): + page_kwargs = self._copy_page_kwargs() + settings = get_settings() + + if 'TRANSLATION_FEED_RSS' in settings: + del settings['TRANSLATION_FEED_RSS'] + if 'TRANSLATION_FEED_ATOM' in settings: + del settings['TRANSLATION_FEED_ATOM'] + page_kwargs['settings'] = settings + + # if atom and rss translations settings are not set + # 'lang_rss_feed_url' and 'lang_atom_feed_url' should + # return None + page = Page(**page_kwargs) + self.assertIsNone(page.lang_atom_feed_url) + self.assertIsNone(page.lang_rss_feed_url) + + settings['TRANSLATION_FEED_RSS'] = None + settings['TRANSLATION_FEED_ATOM'] = None + page_kwargs['settings'] = settings + + # if atom and rss translations settings are None + # 'lang_rss_feed_url' and 'lang_atom_feed_url' should + # return None + page = Page(**page_kwargs) + self.assertIsNone(page.lang_atom_feed_url) + self.assertIsNone(page.lang_rss_feed_url) + + rss_path = '/we/speak/{lang}.rss.xml' + atom_path = '/we/speak/{lang}.atom.xml' + settings['TRANSLATION_FEED_RSS'] = rss_path + settings['TRANSLATION_FEED_ATOM'] = atom_path + page_kwargs['settings'] = settings + + # if the language for the page is set 'lang_rss_feed_url' + # and 'lang_atom_feed_url' should return the formated path + page = Page(**page_kwargs) + self.assertEqual( + page.lang_atom_feed_url, + atom_path.format(lang=DEFAULT_CONFIG['DEFAULT_LANG']) + ) + self.assertEqual( + page.lang_rss_feed_url, + rss_path.format(lang=DEFAULT_CONFIG['DEFAULT_LANG']) + ) + def test_save_as(self): # If a lang is not the default lang, save_as should be set # accordingly. diff --git a/pelican/tests/test_urlwrappers.py b/pelican/tests/test_urlwrappers.py index 8ff3d9d6..8aa63748 100644 --- a/pelican/tests/test_urlwrappers.py +++ b/pelican/tests/test_urlwrappers.py @@ -86,3 +86,61 @@ class TestURLWrapper(unittest.TestCase): self.assertEqual(author1.slug, 'mr-senko') self.assertEqual(author2.slug, 'atodorov') self.assertEqual(author3.slug, 'krasimir') + + def test_atom_feed_url(self): + settings = { + 'URLWRAPPER_FEED_ATOM': None + } + wrapper = URLWrapper("A Smart Person", settings=settings) + + # if '{}_FEED_ATOM' is None, then 'atom_feed_url' should + # also be None + self.assertIsNone(wrapper.atom_feed_url) + + url = '/feed/{slug}.atom.xml' + settings['URLWRAPPER_FEED_ATOM'] = url + wrapper = URLWrapper("A Smart Person", settings=settings) + + # if '{}_FEED_ATOM is set, then 'atom_feed_url' should + # return the url of the atom feed. + self.assertEqual( + wrapper.atom_feed_url, + url.format(slug='a smart person') + ) + + # if we update 'URLWrapper.slug', 'atom_feed_url' + # should also update. + wrapper.slug = 'not-a-smart-person' + self.assertEqual( + wrapper.atom_feed_url, + url.format(slug='not-a-smart-person') + ) + + def test_rss_feed_url(self): + settings = { + 'URLWRAPPER_FEED_RSS': None + } + wrapper = URLWrapper("A Smart Person", settings=settings) + + # if '{}_FEED_ATOM' is None, then 'atom_feed_url' should + # also be None + self.assertIsNone(wrapper.atom_feed_url) + + url = '/feed/{slug}.rss.xml' + settings['URLWRAPPER_FEED_RSS'] = url + wrapper = URLWrapper("A Smart Person", settings=settings) + + # if '{}_FEED_ATOM is set, then 'atom_feed_url' should + # return the url of the atom feed. + self.assertEqual( + wrapper.rss_feed_url, + url.format(slug='a smart person') + ) + + # if we update 'URLWrapper.slug', 'atom_feed_url' + # should also update. + wrapper.slug = 'not-a-smart-person' + self.assertEqual( + wrapper.rss_feed_url, + url.format(slug='not-a-smart-person') + ) diff --git a/pelican/themes/simple/templates/base.html b/pelican/themes/simple/templates/base.html index a1fdcf78..96451469 100644 --- a/pelican/themes/simple/templates/base.html +++ b/pelican/themes/simple/templates/base.html @@ -17,17 +17,23 @@ {% endif %} {% if CATEGORY_FEED_ATOM and category %} - + {% endif %} {% if CATEGORY_FEED_RSS and category %} - + {% endif %} {% if TAG_FEED_ATOM and tag %} - + {% endif %} {% if TAG_FEED_RSS and tag %} - + {% endif %} + {% if TRANSLATION_FEED_ATOM and article %} + + {% endif %} + {% if TRANSLATION_FEED_RSS and article %} + + {% endif %} {% endblock head %} diff --git a/pelican/urlwrappers.py b/pelican/urlwrappers.py index baa8eb23..63f28bd9 100644 --- a/pelican/urlwrappers.py +++ b/pelican/urlwrappers.py @@ -55,6 +55,22 @@ class URLWrapper(object): self._slug_from_name = False self._slug = slug + @property + def atom_feed_url(self): + feed_key = '{}_FEED_ATOM'.format( + self.__class__.__name__.upper()) + feed_url = self.settings.get(feed_key, None) + if feed_url is not None: + return feed_url.format(slug=self.slug) + + @property + def rss_feed_url(self): + feed_key = '{}_FEED_RSS'.format( + self.__class__.__name__.upper()) + feed_url = self.settings.get(feed_key, None) + if feed_url is not None: + return feed_url.format(slug=self.slug) + def as_dict(self): d = self.__dict__ d['name'] = self.name