Add option to exclude empty categories from menu
This commit is contained in:
parent
8b248e7b0f
commit
c1edba9772
4 changed files with 55 additions and 21 deletions
|
@ -262,7 +262,7 @@ class BlogConfigAdmin(BaseAppHookConfig, TranslatableAdmin):
|
||||||
('Layout', {
|
('Layout', {
|
||||||
'fields': (
|
'fields': (
|
||||||
'config.paginate_by', 'config.url_patterns', 'config.template_prefix',
|
'config.paginate_by', 'config.url_patterns', 'config.template_prefix',
|
||||||
'config.menu_structure',
|
'config.menu_structure', 'config.menu_empty_categories',
|
||||||
),
|
),
|
||||||
'classes': ('collapse',)
|
'classes': ('collapse',)
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -66,6 +66,10 @@ class BlogConfigForm(AppDataForm):
|
||||||
choices=get_setting('MENU_TYPES'), initial=MENU_TYPE_COMPLETE,
|
choices=get_setting('MENU_TYPES'), initial=MENU_TYPE_COMPLETE,
|
||||||
help_text=_('Structure of the django CMS menu')
|
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(
|
sitemap_changefreq = forms.ChoiceField(
|
||||||
label=_('Sitemap changefreq'), required=True,
|
label=_('Sitemap changefreq'), required=True,
|
||||||
choices=get_setting('SITEMAP_CHANGEFREQ'),
|
choices=get_setting('SITEMAP_CHANGEFREQ'),
|
||||||
|
|
|
@ -48,33 +48,16 @@ class BlogCategoryMenu(CMSAttachMenu):
|
||||||
if config and config.menu_structure in (MENU_TYPE_COMPLETE, MENU_TYPE_POSTS):
|
if config and config.menu_structure in (MENU_TYPE_COMPLETE, MENU_TYPE_POSTS):
|
||||||
posts_menu = True
|
posts_menu = True
|
||||||
|
|
||||||
if categories_menu:
|
used_categories = []
|
||||||
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)
|
|
||||||
|
|
||||||
if posts_menu:
|
if posts_menu:
|
||||||
posts = Post.objects
|
posts = Post.objects
|
||||||
if hasattr(self, 'instance') and self.instance:
|
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()
|
posts = posts.active_translations(language).distinct()
|
||||||
for post in posts:
|
for post in posts:
|
||||||
post_id = None
|
post_id = None
|
||||||
parent = None
|
parent = None
|
||||||
|
used_categories.extend(post.categories.values_list('pk', flat=True))
|
||||||
if categories_menu:
|
if categories_menu:
|
||||||
category = post.categories.first()
|
category = post.categories.first()
|
||||||
if category:
|
if category:
|
||||||
|
@ -91,6 +74,28 @@ class BlogCategoryMenu(CMSAttachMenu):
|
||||||
)
|
)
|
||||||
nodes.append(node)
|
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
|
return nodes
|
||||||
|
|
||||||
menu_pool.register_menu(BlogCategoryMenu)
|
menu_pool.register_menu(BlogCategoryMenu)
|
||||||
|
|
|
@ -70,6 +70,8 @@ class MenuTest(BaseTest):
|
||||||
posts = self.get_posts()
|
posts = self.get_posts()
|
||||||
|
|
||||||
cats_url = {}
|
cats_url = {}
|
||||||
|
cats_with_post_url = {}
|
||||||
|
cats_without_post_url = {}
|
||||||
posts_url = {}
|
posts_url = {}
|
||||||
|
|
||||||
languages = ('en', 'it')
|
languages = ('en', 'it')
|
||||||
|
@ -77,6 +79,8 @@ class MenuTest(BaseTest):
|
||||||
for lang in languages:
|
for lang in languages:
|
||||||
with smart_override(lang):
|
with smart_override(lang):
|
||||||
cats_url[lang] = set([cat.get_absolute_url() for cat in self.cats if cat.has_translation(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])
|
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
|
# No item in the menu
|
||||||
|
@ -127,6 +131,27 @@ class MenuTest(BaseTest):
|
||||||
self.assertTrue(cats_url[lang].issubset(nodes_url))
|
self.assertTrue(cats_url[lang].issubset(nodes_url))
|
||||||
self.assertTrue(posts_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):
|
def test_modifier(self):
|
||||||
"""
|
"""
|
||||||
Tests if correct category is selected in the menu
|
Tests if correct category is selected in the menu
|
||||||
|
|
Loading…
Reference in a new issue