Add option to exclude empty categories from menu

This commit is contained in:
Iacopo Spalletti 2016-06-28 00:26:38 +02:00
parent 8b248e7b0f
commit c1edba9772
No known key found for this signature in database
GPG Key ID: BDCBC2EB289F60C6
4 changed files with 55 additions and 21 deletions

View File

@ -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',)
}),

View File

@ -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'),

View File

@ -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)

View File

@ -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