Add support for configurable menu structure

This commit is contained in:
Iacopo Spalletti 2015-10-17 15:37:22 +02:00
commit c5e0227565
3 changed files with 140 additions and 35 deletions

View file

@ -9,7 +9,7 @@ from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from parler.models import TranslatableModel, TranslatedFields from parler.models import TranslatableModel, TranslatedFields
from .settings import get_setting from .settings import MENU_TYPE_COMPLETE, get_setting
class BlogConfig(TranslatableModel, AppHookConfig): class BlogConfig(TranslatableModel, AppHookConfig):
@ -54,41 +54,57 @@ class BlogConfigForm(AppDataForm):
label=_('Template prefix'), required=False, initial='', label=_('Template prefix'), required=False, initial='',
help_text=_('Alternative directory to load the blog templates from') 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( object_type = forms.ChoiceField(
label=_('Object type'), required=False, label=_('Object type'), required=False,
choices=get_setting('TYPES'), initial=get_setting('TYPE') choices=get_setting('TYPES'), initial=get_setting('TYPE')
) )
og_type = forms.ChoiceField( og_type = forms.ChoiceField(
label=_('Facebook type'), required=False, 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( og_app_id = forms.CharField(
max_length=200, label=_('Facebook application ID'), required=False, max_length=200, label=_('Facebook application ID'), required=False,
initial=get_setting('FB_PROFILE_ID')
) )
og_profile_id = forms.CharField( og_profile_id = forms.CharField(
max_length=200, label=_('Facebook profile ID'), required=False, max_length=200, label=_('Facebook profile ID'), required=False,
initial=get_setting('FB_PROFILE_ID')
) )
og_publisher = forms.CharField( 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( 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( twitter_type = forms.ChoiceField(
label=_('Twitter type'), required=False, 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( 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( 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( gplus_type = forms.ChoiceField(
label=_('Google+ type'), required=False, 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( 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) setup_config(BlogConfigForm, BlogConfig)

View file

@ -7,7 +7,9 @@ from django.utils.translation import get_language_from_request, ugettext_lazy as
from menus.base import NavigationNode from menus.base import NavigationNode
from menus.menu_pool import menu_pool from menus.menu_pool import menu_pool
from .cms_appconfig import BlogConfig
from .models import BlogCategory, Post from .models import BlogCategory, Post
from .settings import MENU_TYPE_CATEGORIES, MENU_TYPE_COMPLETE, MENU_TYPE_POSTS
class BlogCategoryMenu(CMSAttachMenu): class BlogCategoryMenu(CMSAttachMenu):
@ -18,8 +20,19 @@ class BlogCategoryMenu(CMSAttachMenu):
language = get_language_from_request(request, check_path=True) 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: if hasattr(self, 'instance') and self.instance:
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
if categories_menu:
categories = BlogCategory.objects
if config:
categories = categories.namespace(self.instance.application_namespace) categories = categories.namespace(self.instance.application_namespace)
categories = categories.active_translations(language).distinct() categories = categories.active_translations(language).distinct()
categories = categories.order_by('parent__id', 'translations__name') categories = categories.order_by('parent__id', 'translations__name')
@ -33,17 +46,24 @@ class BlogCategoryMenu(CMSAttachMenu):
) )
nodes.append(node) nodes.append(node)
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)
posts = posts.active_translations(language).distinct() posts = posts.active_translations(language).distinct()
for post in posts: for post in posts:
if categories_menu:
category = post.categories.first() 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( node = NavigationNode(
post.get_title(), post.get_title(),
post.get_absolute_url(language), post.get_absolute_url(language),
'%s-%s' % (post.__class__.__name__, category.pk), post_id,
'%s-%s' % (category.__class__.__name__, category.pk) parent
) )
nodes.append(node) nodes.append(node)

View file

@ -2,11 +2,15 @@
from __future__ import absolute_import, print_function, unicode_literals from __future__ import absolute_import, print_function, unicode_literals
from aldryn_apphooks_config.utils import get_app_instance from aldryn_apphooks_config.utils import get_app_instance
from django.core.cache import cache
from django.utils.translation import activate from django.utils.translation import activate
from menus.menu_pool import menu_pool from menus.menu_pool import menu_pool
from parler.utils.context import smart_override, switch_language from parler.utils.context import smart_override, switch_language
from djangocms_blog.views import CategoryEntriesView, PostDetailView 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 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)]) cats_url = set([cat.get_absolute_url() for cat in self.cats if cat.has_translation(lang)])
self.assertTrue(cats_url.issubset(nodes_url)) 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): def test_modifier(self):
""" """
Tests if correct category is selected in the menu Tests if correct category is selected in the menu