diff --git a/djangocms_blog/sitemaps/__init__.py b/djangocms_blog/sitemaps/__init__.py index 9d43d6d..2314bee 100644 --- a/djangocms_blog/sitemaps/__init__.py +++ b/djangocms_blog/sitemaps/__init__.py @@ -8,9 +8,18 @@ from parler.utils.context import smart_override from ..models import Post from ..settings import get_setting +try: + from django.urls.exceptions import NoReverseMatch +except ImportError: + from django.core.urlresolvers import NoReverseMatch + class BlogSitemap(Sitemap): + def __init__(self, *args, **kwargs): + super(BlogSitemap, self).__init__(*args, **kwargs) + self.url_cache = {} + def priority(self, obj): if obj and obj.app_config: return obj.app_config.sitemap_priority @@ -23,12 +32,27 @@ class BlogSitemap(Sitemap): def location(self, obj): with smart_override(obj.get_current_language()): - return obj.get_absolute_url(obj.get_current_language()) + return self.url_cache[obj.get_current_language()][obj] def items(self): items = [] + self.url_cache.clear() for lang in get_language_list(): - items.extend(Post.objects.translated(lang).language(lang).published()) + self.url_cache[lang] = {} + posts = Post.objects.translated(lang).language(lang).published() + for post in posts: + # check if the post actually has a url before appending + # if a post is published but the associated app config is not + # then this post will not have a url + try: + with smart_override(post.get_current_language()): + self.url_cache[lang][post] = post.get_absolute_url() + except NoReverseMatch: + # couldn't determine the url of the post so pass on it + continue + + items.append(post) + return items def lastmod(self, obj): diff --git a/tests/test_views.py b/tests/test_views.py index 2c5d3d4..8ffd347 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -6,6 +6,7 @@ import os.path from aldryn_apphooks_config.utils import get_app_instance from cms.api import add_plugin from cms.toolbar.items import ModalItem +from cms.utils.apphook_reload import reload_urlconf from django.contrib.auth.models import AnonymousUser from django.core.exceptions import ImproperlyConfigured from django.core.urlresolvers import reverse @@ -418,6 +419,22 @@ class ViewTest(BaseTest): sitemap.location(item), item.get_absolute_url() ) + def test_sitemap_with_unpublished(self): + posts = self.get_posts() + pages = self.get_pages() + sitemap = BlogSitemap() + + self.assertEqual(len(sitemap.items()), 4) + + # unpublish all the pages + for page in pages: + page.unpublish('en') + page.unpublish('it') + + reload_urlconf() + + self.assertEqual(len(sitemap.items()), 0) + def test_sitemap_config(self): posts = self.get_posts() self.app_config_1.app_data.config.sitemap_changefreq = 'daily'