diff --git a/djangocms_blog/cms_appconfig.py b/djangocms_blog/cms_appconfig.py index c23c4d3..5c0927b 100644 --- a/djangocms_blog/cms_appconfig.py +++ b/djangocms_blog/cms_appconfig.py @@ -9,7 +9,7 @@ from django.db import models from django.utils.translation import ugettext_lazy as _ from parler.models import TranslatableModel, TranslatedFields -from .settings import get_setting +from .settings import MENU_TYPE_COMPLETE, get_setting class BlogConfig(TranslatableModel, AppHookConfig): @@ -54,41 +54,57 @@ class BlogConfigForm(AppDataForm): label=_('Template prefix'), required=False, initial='', help_text=_('Alternative directory to load the blog templates from') ) + menu_structure = forms.ChoiceField( + label=_('Menu structure'), required=True, + choices=get_setting('MENU_TYPES'), initial=MENU_TYPE_COMPLETE, + help_text=_('Structure of the django CMS menu') + ) object_type = forms.ChoiceField( label=_('Object type'), required=False, choices=get_setting('TYPES'), initial=get_setting('TYPE') ) og_type = forms.ChoiceField( label=_('Facebook type'), required=False, - choices=get_setting('FB_TYPES'), initial=get_setting('FB_TYPES')[0][0] + choices=get_setting('FB_TYPES'), initial=get_setting('FB_TYPE') ) og_app_id = forms.CharField( max_length=200, label=_('Facebook application ID'), required=False, + initial=get_setting('FB_PROFILE_ID') ) og_profile_id = forms.CharField( max_length=200, label=_('Facebook profile ID'), required=False, + initial=get_setting('FB_PROFILE_ID') ) og_publisher = forms.CharField( - max_length=200, label=_('Facebook page URL'), required=False + max_length=200, label=_('Facebook page URL'), required=False, + initial=get_setting('FB_PUBLISHER') ) og_author_url = forms.CharField( - max_length=200, label=_('Facebook author URL'), required=False + max_length=200, label=_('Facebook author URL'), required=False, + initial=get_setting('FB_AUTHOR_URL') + ) + og_author = forms.CharField( + max_length=200, label=_('Facebook author'), required=False, + initial=get_setting('FB_AUTHOR') ) twitter_type = forms.ChoiceField( label=_('Twitter type'), required=False, - choices=get_setting('TWITTER_TYPES'), initial=get_setting('TWITTER_TYPES')[0][0] + choices=get_setting('TWITTER_TYPES'), initial=get_setting('TWITTER_TYPE') ) twitter_site = forms.CharField( - max_length=200, label=_('Twitter site handle'), required=False + max_length=200, label=_('Twitter site handle'), required=False, + initial=get_setting('TWITTER_SITE') ) twitter_author = forms.CharField( - max_length=200, label=_('Twitter author handle'), required=False + max_length=200, label=_('Twitter author handle'), required=False, + initial=get_setting('TWITTER_AUTHOR') ) gplus_type = forms.ChoiceField( label=_('Google+ type'), required=False, - choices=get_setting('GPLUS_TYPES'), initial=get_setting('GPLUS_TYPES')[0][0] + choices=get_setting('GPLUS_TYPES'), initial=get_setting('GPLUS_TYPE') ) gplus_author = forms.CharField( - max_length=200, label=_('Google+ author name'), required=False + max_length=200, label=_('Google+ author name'), required=False, + initial=get_setting('GPLUS_AUTHOR') ) setup_config(BlogConfigForm, BlogConfig) diff --git a/djangocms_blog/menu.py b/djangocms_blog/menu.py index a36730f..6b4e883 100644 --- a/djangocms_blog/menu.py +++ b/djangocms_blog/menu.py @@ -7,7 +7,9 @@ from django.utils.translation import get_language_from_request, ugettext_lazy as from menus.base import NavigationNode from menus.menu_pool import menu_pool +from .cms_appconfig import BlogConfig from .models import BlogCategory, Post +from .settings import MENU_TYPE_CATEGORIES, MENU_TYPE_COMPLETE, MENU_TYPE_POSTS class BlogCategoryMenu(CMSAttachMenu): @@ -18,34 +20,52 @@ class BlogCategoryMenu(CMSAttachMenu): language = get_language_from_request(request, check_path=True) - categories = BlogCategory.objects + categories_menu = False + posts_menu = False + config = False if hasattr(self, 'instance') and self.instance: - 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(), - '%s-%s' % (category.__class__.__name__, category.pk), - ('%s-%s' % (category.__class__.__name__, category.parent.id) if category.parent - else None) - ) - nodes.append(node) + config = BlogConfig.objects.get(namespace=self.instance.application_namespace) + if config.menu_structure in (MENU_TYPE_COMPLETE, MENU_TYPE_CATEGORIES): + categories_menu = True + if config.menu_structure in (MENU_TYPE_COMPLETE, MENU_TYPE_POSTS): + posts_menu = True - posts = Post.objects - if hasattr(self, 'instance') and self.instance: - posts = posts.namespace(self.instance.application_namespace) - posts = posts.active_translations(language).distinct() - for post in posts: - category = post.categories.first() - node = NavigationNode( - post.get_title(), - post.get_absolute_url(language), - '%s-%s' % (post.__class__.__name__, category.pk), - '%s-%s' % (category.__class__.__name__, category.pk) - ) - nodes.append(node) + 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(), + '%s-%s' % (category.__class__.__name__, category.pk), + ('%s-%s' % (category.__class__.__name__, category.parent.id) if category.parent + else None) + ) + nodes.append(node) + + if posts_menu: + posts = Post.objects + if hasattr(self, 'instance') and self.instance: + posts = posts.namespace(self.instance.application_namespace) + posts = posts.active_translations(language).distinct() + for post in posts: + if categories_menu: + category = post.categories.first() + parent = '%s-%s' % (category.__class__.__name__, category.pk) + post_id = '%s-%s' % (post.__class__.__name__, post.pk), + else: + parent = None + post_id = '%s-%s' % (post.__class__.__name__, post.pk), + node = NavigationNode( + post.get_title(), + post.get_absolute_url(language), + post_id, + parent + ) + nodes.append(node) return nodes diff --git a/tests/test_menu.py b/tests/test_menu.py index 8830468..62275b2 100644 --- a/tests/test_menu.py +++ b/tests/test_menu.py @@ -2,11 +2,15 @@ from __future__ import absolute_import, print_function, unicode_literals from aldryn_apphooks_config.utils import get_app_instance +from django.core.cache import cache from django.utils.translation import activate from menus.menu_pool import menu_pool from parler.utils.context import smart_override, switch_language from djangocms_blog.views import CategoryEntriesView, PostDetailView +from djangocms_blog.settings import ( + MENU_TYPE_CATEGORIES, MENU_TYPE_COMPLETE, MENU_TYPE_NONE, MENU_TYPE_POSTS, +) from . import BaseTest @@ -44,6 +48,71 @@ class MenuTest(BaseTest): cats_url = set([cat.get_absolute_url() for cat in self.cats if cat.has_translation(lang)]) self.assertTrue(cats_url.issubset(nodes_url)) + def test_menu_options(self): + """ + Tests menu structure based on menu_structure configuration + """ + posts = self.get_posts() + self.get_pages() + + cats_url = {} + posts_url = {} + + languages = ('en', 'it') + + 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)]) + posts_url[lang] = set([post.get_absolute_url() for post in posts if post.has_translation(lang) and post.app_config == self.app_config_1]) + + # No item in the menu + self.app_config_1.app_data.config.menu_structure = MENU_TYPE_NONE + self.app_config_1.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, namespace='BlogCategoryMenu') + nodes_url = set([node.url for node in nodes]) + self.assertFalse(cats_url[lang].issubset(nodes_url)) + self.assertFalse(posts_url[lang].issubset(nodes_url)) + + # Only posts in the menu + self.app_config_1.app_data.config.menu_structure = MENU_TYPE_POSTS + self.app_config_1.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, namespace='BlogCategoryMenu') + nodes_url = set([node.url for node in nodes]) + self.assertFalse(cats_url[lang].issubset(nodes_url)) + self.assertTrue(posts_url[lang].issubset(nodes_url)) + + # Only categories in the menu + self.app_config_1.app_data.config.menu_structure = MENU_TYPE_CATEGORIES + self.app_config_1.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, namespace='BlogCategoryMenu') + nodes_url = set([node.url for node in nodes]) + self.assertTrue(cats_url[lang].issubset(nodes_url)) + self.assertFalse(posts_url[lang].issubset(nodes_url)) + + # Both types in the menu + self.app_config_1.app_data.config.menu_structure = MENU_TYPE_COMPLETE + self.app_config_1.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, namespace='BlogCategoryMenu') + nodes_url = set([node.url for node in nodes]) + self.assertTrue(cats_url[lang].issubset(nodes_url)) + self.assertTrue(posts_url[lang].issubset(nodes_url)) + def test_modifier(self): """ Tests if correct category is selected in the menu