diff --git a/djangocms_blog/admin.py b/djangocms_blog/admin.py index 7ea2e7c..b849c2f 100755 --- a/djangocms_blog/admin.py +++ b/djangocms_blog/admin.py @@ -262,7 +262,7 @@ class BlogConfigAdmin(BaseAppHookConfig, TranslatableAdmin): ('Layout', { 'fields': ( 'config.paginate_by', 'config.url_patterns', 'config.template_prefix', - 'config.menu_structure', + 'config.menu_structure', 'config.menu_empty_categories', ), 'classes': ('collapse',) }), diff --git a/djangocms_blog/cms_appconfig.py b/djangocms_blog/cms_appconfig.py index e7e028d..798cf90 100644 --- a/djangocms_blog/cms_appconfig.py +++ b/djangocms_blog/cms_appconfig.py @@ -66,6 +66,10 @@ class BlogConfigForm(AppDataForm): choices=get_setting('MENU_TYPES'), initial=MENU_TYPE_COMPLETE, help_text=_('Structure of the django CMS menu') ) + menu_empty_categories = forms.BooleanField( + label=_('Show empty categories in menu'), initial=True, required=False, + help_text=_('Show categories with no post attached in the menu') + ) sitemap_changefreq = forms.ChoiceField( label=_('Sitemap changefreq'), required=True, choices=get_setting('SITEMAP_CHANGEFREQ'), diff --git a/djangocms_blog/cms_menus.py b/djangocms_blog/cms_menus.py index 426ac09..2b03fcd 100644 --- a/djangocms_blog/cms_menus.py +++ b/djangocms_blog/cms_menus.py @@ -48,33 +48,16 @@ class BlogCategoryMenu(CMSAttachMenu): if config and config.menu_structure in (MENU_TYPE_COMPLETE, MENU_TYPE_POSTS): posts_menu = True - if categories_menu: - categories = BlogCategory.objects - if config: - categories = categories.namespace(self.instance.application_namespace) - categories = categories.active_translations(language).distinct() - categories = categories.order_by('parent__id', 'translations__name') - for category in categories: - node = NavigationNode( - category.name, - category.get_absolute_url(), - '{0}-{1}'.format(category.__class__.__name__, category.pk), - ( - '{0}-{1}'.format( - category.__class__.__name__, category.parent.id - ) if category.parent else None - ) - ) - nodes.append(node) - + used_categories = [] if posts_menu: posts = Post.objects if hasattr(self, 'instance') and self.instance: - posts = posts.namespace(self.instance.application_namespace) + posts = posts.namespace(self.instance.application_namespace).on_site() posts = posts.active_translations(language).distinct() for post in posts: post_id = None parent = None + used_categories.extend(post.categories.values_list('pk', flat=True)) if categories_menu: category = post.categories.first() if category: @@ -91,6 +74,28 @@ class BlogCategoryMenu(CMSAttachMenu): ) nodes.append(node) + if categories_menu: + categories = BlogCategory.objects + if config: + categories = categories.namespace(self.instance.application_namespace) + if config and not config.menu_empty_categories: + categories = categories.filter(pk__in=used_categories) + else: + categories = categories.active_translations(language).distinct() + categories = categories.order_by('parent__id', 'translations__name') + for category in categories: + node = NavigationNode( + category.name, + category.get_absolute_url(), + '{0}-{1}'.format(category.__class__.__name__, category.pk), + ( + '{0}-{1}'.format( + category.__class__.__name__, category.parent.id + ) if category.parent else None + ) + ) + nodes.append(node) + return nodes menu_pool.register_menu(BlogCategoryMenu) diff --git a/tests/test_menu.py b/tests/test_menu.py index 5400592..89482eb 100644 --- a/tests/test_menu.py +++ b/tests/test_menu.py @@ -70,6 +70,8 @@ class MenuTest(BaseTest): posts = self.get_posts() cats_url = {} + cats_with_post_url = {} + cats_without_post_url = {} posts_url = {} languages = ('en', 'it') @@ -77,6 +79,8 @@ class MenuTest(BaseTest): for lang in languages: with smart_override(lang): cats_url[lang] = set([cat.get_absolute_url() for cat in self.cats if cat.has_translation(lang)]) + cats_with_post_url[lang] = set([cat.get_absolute_url() for cat in self.cats if cat.has_translation(lang) and cat.blog_posts.published().exists()]) + cats_without_post_url[lang] = cats_url[lang].difference(cats_with_post_url[lang]) posts_url[lang] = set([post.get_absolute_url(lang) for post in posts if post.has_translation(lang) and post.app_config == self.app_config_1]) # No item in the menu @@ -127,6 +131,27 @@ class MenuTest(BaseTest): self.assertTrue(cats_url[lang].issubset(nodes_url)) self.assertTrue(posts_url[lang].issubset(nodes_url)) + # Both types in the menu + self.app_config_1.app_data.config.menu_empty_categories = False + self.app_config_1.save() + self.app_config_2.app_data.config.menu_empty_categories = False + self.app_config_2.save() + cache.clear() + for lang in languages: + request = self.get_page_request(None, self.user, r'/%s/page-two/' % lang) + with smart_override(lang): + nodes = menu_pool.get_nodes(request) + nodes_url = set([node.url for node in nodes]) + self.assertTrue(cats_with_post_url[lang].issubset(nodes_url)) + self.assertFalse(cats_without_post_url[lang].intersection(nodes_url)) + self.assertTrue(posts_url[lang].issubset(nodes_url)) + # Both types in the menu + self.app_config_1.app_data.config.menu_empty_categories = True + self.app_config_1.save() + self.app_config_2.app_data.config.menu_empty_categories = True + self.app_config_2.save() + cache.clear() + def test_modifier(self): """ Tests if correct category is selected in the menu