Merge pull request #200 from nephila/feature/publish_button
Add publish button to the toolbar
This commit is contained in:
commit
18ea7bbd88
5 changed files with 118 additions and 5 deletions
|
@ -3,12 +3,13 @@
|
||||||
History
|
History
|
||||||
-------
|
-------
|
||||||
|
|
||||||
0.6.4 (unreleased)
|
0.7.0 (unreleased)
|
||||||
++++++++++++++++++
|
++++++++++++++++++
|
||||||
|
|
||||||
* Make categories non required
|
* Make categories non required
|
||||||
* Fix tests with parler>=1.6
|
* Fix tests with parler>=1.6
|
||||||
* Use all_languages_column to admin
|
* Use all_languages_column to admin
|
||||||
|
* Add publish button
|
||||||
|
|
||||||
0.6.3 (2015-12-22)
|
0.6.3 (2015-12-22)
|
||||||
++++++++++++++++++
|
++++++++++++++++++
|
||||||
|
|
|
@ -7,9 +7,12 @@ from aldryn_apphooks_config.admin import BaseAppHookConfig, ModelAppHookConfig
|
||||||
from cms.admin.placeholderadmin import FrontendEditableAdminMixin, PlaceholderAdminMixin
|
from cms.admin.placeholderadmin import FrontendEditableAdminMixin, PlaceholderAdminMixin
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.conf.urls import url
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
from django.http import HttpResponseRedirect
|
||||||
from django.utils.six import callable
|
from django.utils.six import callable
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import get_language_from_request, ugettext_lazy as _
|
||||||
from parler.admin import TranslatableAdmin
|
from parler.admin import TranslatableAdmin
|
||||||
|
|
||||||
from .cms_appconfig import BlogConfig
|
from .cms_appconfig import BlogConfig
|
||||||
|
@ -73,8 +76,35 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin,
|
||||||
'default_published': 'publish'
|
'default_published': 'publish'
|
||||||
}
|
}
|
||||||
|
|
||||||
def languages(self, obj):
|
def get_urls(self):
|
||||||
return ','.join(obj.get_available_languages())
|
"""
|
||||||
|
Customize the modeladmin urls
|
||||||
|
"""
|
||||||
|
urls = [
|
||||||
|
url(r'^publish/([0-9]+)/$', self.admin_site.admin_view(self.publish_post),
|
||||||
|
name='djangocms_blog_publish_article'),
|
||||||
|
]
|
||||||
|
urls.extend(super(PostAdmin, self).get_urls())
|
||||||
|
return urls
|
||||||
|
|
||||||
|
def publish_post(self, request, pk):
|
||||||
|
"""
|
||||||
|
Admin view to publish a single post
|
||||||
|
:param request: request
|
||||||
|
:param pk: primary key of the post to publish
|
||||||
|
:return: Redirect to the post itself (if found) or fallback urls
|
||||||
|
"""
|
||||||
|
language = get_language_from_request(request, check_path=True)
|
||||||
|
try:
|
||||||
|
post = Post.objects.get(pk=int(pk))
|
||||||
|
post.publish = True
|
||||||
|
post.save()
|
||||||
|
return HttpResponseRedirect(post.get_absolute_url(language))
|
||||||
|
except Exception:
|
||||||
|
try:
|
||||||
|
return HttpResponseRedirect(request.META['HTTP_REFERER'])
|
||||||
|
except KeyError:
|
||||||
|
return HttpResponseRedirect(reverse('djangocms_blog:posts-latest'))
|
||||||
|
|
||||||
def formfield_for_dbfield(self, db_field, **kwargs):
|
def formfield_for_dbfield(self, db_field, **kwargs):
|
||||||
field = super(PostAdmin, self).formfield_for_dbfield(db_field, **kwargs)
|
field = super(PostAdmin, self).formfield_for_dbfield(db_field, **kwargs)
|
||||||
|
@ -87,6 +117,12 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin,
|
||||||
return field
|
return field
|
||||||
|
|
||||||
def get_fieldsets(self, request, obj=None):
|
def get_fieldsets(self, request, obj=None):
|
||||||
|
"""
|
||||||
|
Customize the fieldsets according to the app settings
|
||||||
|
:param request: request
|
||||||
|
:param obj: post
|
||||||
|
:return: fieldsets configuration
|
||||||
|
"""
|
||||||
app_config_default = self._app_config_select(request, obj)
|
app_config_default = self._app_config_select(request, obj)
|
||||||
if app_config_default is None and request.method == 'GET':
|
if app_config_default is None and request.method == 'GET':
|
||||||
return super(PostAdmin, self).get_fieldsets(request, obj)
|
return super(PostAdmin, self).get_fieldsets(request, obj)
|
||||||
|
@ -132,6 +168,9 @@ class BlogConfigAdmin(BaseAppHookConfig, TranslatableAdmin):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def declared_fieldsets(self):
|
def declared_fieldsets(self):
|
||||||
|
"""
|
||||||
|
Fieldsets configuration
|
||||||
|
"""
|
||||||
return [
|
return [
|
||||||
(None, {
|
(None, {
|
||||||
'fields': ('type', 'namespace', 'app_title', 'object_name')
|
'fields': ('type', 'namespace', 'app_title', 'object_name')
|
||||||
|
|
|
@ -3,6 +3,7 @@ from __future__ import absolute_import, print_function, unicode_literals
|
||||||
|
|
||||||
from cms.toolbar_base import CMSToolbar
|
from cms.toolbar_base import CMSToolbar
|
||||||
from cms.toolbar_pool import toolbar_pool
|
from cms.toolbar_pool import toolbar_pool
|
||||||
|
from cms.utils.urlutils import admin_reverse
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.utils.translation import override, ugettext_lazy as _
|
from django.utils.translation import override, ugettext_lazy as _
|
||||||
|
|
||||||
|
@ -33,6 +34,22 @@ class BlogToolbar(CMSToolbar):
|
||||||
'admin:djangocms_blog_post_change', args=(current_post.pk,)),
|
'admin:djangocms_blog_post_change', args=(current_post.pk,)),
|
||||||
active=True)
|
active=True)
|
||||||
|
|
||||||
|
def add_publish_button(self):
|
||||||
|
"""
|
||||||
|
Adds the publish button to the toolbar if the current post is unpublished
|
||||||
|
"""
|
||||||
|
current_post = getattr(self.request, get_setting('CURRENT_POST_IDENTIFIER'), None)
|
||||||
|
if (self.toolbar.edit_mode and current_post and
|
||||||
|
not current_post.publish and
|
||||||
|
self.request.user.has_perm('djangocms_blog.change_post')
|
||||||
|
): # pragma: no cover # NOQA
|
||||||
|
classes = ['cms-btn-action', 'blog-publish']
|
||||||
|
title = _('Publish {0} now').format(current_post.app_config.object_name)
|
||||||
|
|
||||||
|
url = admin_reverse('djangocms_blog_publish_article', args=(current_post.pk,))
|
||||||
|
|
||||||
|
self.toolbar.add_button(title, url=url, extra_classes=classes, side=self.toolbar.RIGHT)
|
||||||
|
|
||||||
def post_template_populate(self):
|
def post_template_populate(self):
|
||||||
current_post = getattr(self.request, get_setting('CURRENT_POST_IDENTIFIER'), None)
|
current_post = getattr(self.request, get_setting('CURRENT_POST_IDENTIFIER'), None)
|
||||||
if current_post and self.request.user.has_perm('djangocms_blog.change_post'): # pragma: no cover # NOQA
|
if current_post and self.request.user.has_perm('djangocms_blog.change_post'): # pragma: no cover # NOQA
|
||||||
|
@ -52,3 +69,4 @@ class BlogToolbar(CMSToolbar):
|
||||||
menu.remove_item(pagetags)
|
menu.remove_item(pagetags)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
self.add_publish_button()
|
||||||
|
|
|
@ -34,6 +34,8 @@ class AdminTest(BaseTest):
|
||||||
admin.autodiscover()
|
admin.autodiscover()
|
||||||
|
|
||||||
def test_admin_post_views(self):
|
def test_admin_post_views(self):
|
||||||
|
self.get_pages()
|
||||||
|
|
||||||
post_admin = admin.site._registry[Post]
|
post_admin = admin.site._registry[Post]
|
||||||
request = self.get_page_request('/', self.user, r'/en/blog/', edit=False)
|
request = self.get_page_request('/', self.user, r'/en/blog/', edit=False)
|
||||||
|
|
||||||
|
@ -50,6 +52,28 @@ class AdminTest(BaseTest):
|
||||||
self.assertContains(response, '<input id="id_slug" maxlength="50" name="slug" type="text" value="first-post" />')
|
self.assertContains(response, '<input id="id_slug" maxlength="50" name="slug" type="text" value="first-post" />')
|
||||||
self.assertContains(response, '<option value="%s" selected="selected">Blog / sample_app</option>' % self.app_config_1.pk)
|
self.assertContains(response, '<option value="%s" selected="selected">Blog / sample_app</option>' % self.app_config_1.pk)
|
||||||
|
|
||||||
|
# Test for publish view
|
||||||
|
post.publish = False
|
||||||
|
post.save()
|
||||||
|
response = post_admin.publish_post(request, str(post.pk))
|
||||||
|
# Redirects to current post
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
self.assertEqual(response['Location'], post.get_absolute_url())
|
||||||
|
post = self.reload_model(post)
|
||||||
|
# post is publshed
|
||||||
|
self.assertTrue(post.publish)
|
||||||
|
|
||||||
|
# Non-existing post is redirected to posts list
|
||||||
|
response = post_admin.publish_post(request, str('1000000'))
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
self.assertEqual(response['Location'], reverse('djangocms_blog:posts-latest'))
|
||||||
|
|
||||||
|
# unless a referer is set
|
||||||
|
request.META['HTTP_REFERER'] = '/'
|
||||||
|
response = post_admin.publish_post(request, str('1000000'))
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
self.assertEqual(response['Location'], '/')
|
||||||
|
|
||||||
def test_admin_blogconfig_views(self):
|
def test_admin_blogconfig_views(self):
|
||||||
post_admin = admin.site._registry[BlogConfig]
|
post_admin = admin.site._registry[BlogConfig]
|
||||||
request = self.get_page_request('/', self.user, r'/en/blog/', edit=False)
|
request = self.get_page_request('/', self.user, r'/en/blog/', edit=False)
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import absolute_import, print_function, unicode_literals
|
from __future__ import absolute_import, print_function, unicode_literals
|
||||||
|
|
||||||
from cms.toolbar.items import ModalItem
|
from cms.toolbar.items import ButtonList, ModalItem
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
|
from django.utils.encoding import force_text
|
||||||
|
|
||||||
from djangocms_blog.models import BLOG_CURRENT_POST_IDENTIFIER
|
from djangocms_blog.models import BLOG_CURRENT_POST_IDENTIFIER
|
||||||
|
|
||||||
|
@ -20,9 +21,39 @@ class ToolbarTest(BaseTest):
|
||||||
pages = self.get_pages()
|
pages = self.get_pages()
|
||||||
request = self.get_page_request(pages[0], self.user, r'/en/blog/', edit=True)
|
request = self.get_page_request(pages[0], self.user, r'/en/blog/', edit=True)
|
||||||
setattr(request, BLOG_CURRENT_POST_IDENTIFIER, posts[0])
|
setattr(request, BLOG_CURRENT_POST_IDENTIFIER, posts[0])
|
||||||
|
|
||||||
|
posts[0].publish = False
|
||||||
|
posts[0].save()
|
||||||
toolbar = CMSToolbar(request)
|
toolbar = CMSToolbar(request)
|
||||||
|
toolbar.populate()
|
||||||
|
toolbar.post_template_populate()
|
||||||
toolbar.get_left_items()
|
toolbar.get_left_items()
|
||||||
blog_menu = toolbar.menus['djangocms_blog']
|
blog_menu = toolbar.menus['djangocms_blog']
|
||||||
self.assertEqual(len(blog_menu.find_items(ModalItem, url=reverse('admin:djangocms_blog_post_changelist'))), 1)
|
self.assertEqual(len(blog_menu.find_items(ModalItem, url=reverse('admin:djangocms_blog_post_changelist'))), 1)
|
||||||
self.assertEqual(len(blog_menu.find_items(ModalItem, url=reverse('admin:djangocms_blog_post_add'))), 1)
|
self.assertEqual(len(blog_menu.find_items(ModalItem, url=reverse('admin:djangocms_blog_post_add'))), 1)
|
||||||
self.assertEqual(len(blog_menu.find_items(ModalItem, url=reverse('admin:djangocms_blog_post_change', args=(posts[0].pk,)))), 1)
|
self.assertEqual(len(blog_menu.find_items(ModalItem, url=reverse('admin:djangocms_blog_post_change', args=(posts[0].pk,)))), 1)
|
||||||
|
|
||||||
|
# Publish button only appears if current post is unpublished
|
||||||
|
right = toolbar.get_right_items()
|
||||||
|
buttons = sum([item.buttons for item in right if isinstance(item, ButtonList)], [])
|
||||||
|
self.assertTrue([button for button in buttons if force_text(button.name) == 'Publish Blog now'])
|
||||||
|
|
||||||
|
# Publish button does not appears if current post is published
|
||||||
|
posts[0].publish = True
|
||||||
|
posts[0].save()
|
||||||
|
toolbar = CMSToolbar(request)
|
||||||
|
toolbar.populate()
|
||||||
|
toolbar.post_template_populate()
|
||||||
|
right = toolbar.get_right_items()
|
||||||
|
buttons = sum([item.buttons for item in right if isinstance(item, ButtonList)], [])
|
||||||
|
self.assertFalse([button for button in buttons if force_text(button.name) == 'Publish Blog now'])
|
||||||
|
|
||||||
|
# Publish button does not appears if other posts but the current one are unpublished
|
||||||
|
posts[1].publish = True
|
||||||
|
posts[1].save()
|
||||||
|
toolbar = CMSToolbar(request)
|
||||||
|
toolbar.populate()
|
||||||
|
toolbar.post_template_populate()
|
||||||
|
right = toolbar.get_right_items()
|
||||||
|
buttons = sum([item.buttons for item in right if isinstance(item, ButtonList)], [])
|
||||||
|
self.assertFalse([button for button in buttons if force_text(button.name) == 'Publish Blog now'])
|
||||||
|
|
Loading…
Reference in a new issue