Merge branch 'develop' of github.com:nephila/djangocms-blog into develop
This commit is contained in:
commit
35f2b47905
15 changed files with 311 additions and 64 deletions
|
@ -1,3 +1,4 @@
|
|||
tests/*
|
||||
docs/*
|
||||
djangocms_blog/south_migrations/*
|
||||
djangocms_blog/migrations/*
|
||||
|
|
|
@ -3,11 +3,15 @@
|
|||
History
|
||||
-------
|
||||
|
||||
0.6.4 (unreleased)
|
||||
0.7.0 (unreleased)
|
||||
++++++++++++++++++
|
||||
|
||||
* Make categories non required
|
||||
* Fix tests with parler>=1.6
|
||||
* Use all_languages_column to admin
|
||||
* Add publish button
|
||||
* Fix issues in migrations. Thanks @skirsdeda
|
||||
* Fix selecting current menu item according to menu layout
|
||||
|
||||
0.6.3 (2015-12-22)
|
||||
++++++++++++++++++
|
||||
|
|
|
@ -190,12 +190,17 @@ suited for your deployment.
|
|||
`Auto setup <auto_setup>`_:
|
||||
|
||||
* Create a new django CMS page
|
||||
* Go to Advanced settings and select Blog from the Application selector and
|
||||
create an application configuration;
|
||||
* Go to **Advanced settings** and select Blog from the **Application** selector and
|
||||
create an **Application configuration**;
|
||||
* Eventually customise the Application instance name;
|
||||
* Publish the page
|
||||
* Restart the project instance to properly load blog urls.
|
||||
|
||||
.. warning:: After adding the apphook to the page you **cannot** change the **Instance Namspace**
|
||||
field for the defined **AppHokConfig**; if you want to change it, create a new one
|
||||
with the correct namespace, go in the CMS page **Advanced settings** and switch to the
|
||||
new **Application configuration**
|
||||
|
||||
* Add and edit blog by creating them in the admin or using the toolbar,
|
||||
and the use the `django CMS frontend editor <http://django-cms.readthedocs.org/en/support-3.0.x/user/reference/page_admin.html#the-interface>`_
|
||||
to edit the blog content:
|
||||
|
|
|
@ -7,9 +7,12 @@ from aldryn_apphooks_config.admin import BaseAppHookConfig, ModelAppHookConfig
|
|||
from cms.admin.placeholderadmin import FrontendEditableAdminMixin, PlaceholderAdminMixin
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.conf.urls import url
|
||||
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.translation import ugettext_lazy as _
|
||||
from django.utils.translation import get_language_from_request, ugettext_lazy as _
|
||||
from parler.admin import TranslatableAdmin
|
||||
|
||||
from .cms_appconfig import BlogConfig
|
||||
|
@ -25,6 +28,7 @@ except ImportError:
|
|||
|
||||
|
||||
class BlogCategoryAdmin(EnhancedModelAdminMixin, ModelAppHookConfig, TranslatableAdmin):
|
||||
|
||||
def get_prepopulated_fields(self, request, obj=None):
|
||||
app_config_default = self._app_config_select(request, obj)
|
||||
if app_config_default is None and request.method == 'GET':
|
||||
|
@ -41,7 +45,8 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin,
|
|||
ModelAppHookConfig, TranslatableAdmin):
|
||||
form = PostAdminForm
|
||||
list_display = [
|
||||
'title', 'author', 'date_published', 'app_config', 'languages', 'date_published_end'
|
||||
'title', 'author', 'date_published', 'app_config', 'all_languages_column',
|
||||
'date_published_end'
|
||||
]
|
||||
list_filter = ('app_config',)
|
||||
date_hierarchy = 'date_published'
|
||||
|
@ -71,8 +76,35 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin,
|
|||
'default_published': 'publish'
|
||||
}
|
||||
|
||||
def languages(self, obj):
|
||||
return ','.join(obj.get_available_languages())
|
||||
def get_urls(self):
|
||||
"""
|
||||
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):
|
||||
field = super(PostAdmin, self).formfield_for_dbfield(db_field, **kwargs)
|
||||
|
@ -85,6 +117,12 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin,
|
|||
return field
|
||||
|
||||
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)
|
||||
if app_config_default is None and request.method == 'GET':
|
||||
return super(PostAdmin, self).get_fieldsets(request, obj)
|
||||
|
@ -130,6 +168,9 @@ class BlogConfigAdmin(BaseAppHookConfig, TranslatableAdmin):
|
|||
|
||||
@property
|
||||
def declared_fieldsets(self):
|
||||
"""
|
||||
Fieldsets configuration
|
||||
"""
|
||||
return [
|
||||
(None, {
|
||||
'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_pool import toolbar_pool
|
||||
from cms.utils.urlutils import admin_reverse
|
||||
from django.core.urlresolvers import reverse
|
||||
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,)),
|
||||
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):
|
||||
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
|
||||
|
@ -52,3 +69,4 @@ class BlogToolbar(CMSToolbar):
|
|||
menu.remove_item(pagetags)
|
||||
except ImportError:
|
||||
pass
|
||||
self.add_publish_button()
|
||||
|
|
|
@ -1,21 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
from cms.apphook_pool import apphook_pool
|
||||
from cms.menu_bases import CMSAttachMenu
|
||||
from django.core.urlresolvers import resolve
|
||||
from django.db.models.signals import post_delete, post_save
|
||||
from django.utils.translation import get_language_from_request, ugettext_lazy as _
|
||||
from menus.base import NavigationNode
|
||||
from menus.base import Modifier, 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
|
||||
from .settings import MENU_TYPE_CATEGORIES, MENU_TYPE_COMPLETE, MENU_TYPE_POSTS, get_setting
|
||||
|
||||
|
||||
class BlogCategoryMenu(CMSAttachMenu):
|
||||
"""
|
||||
Main menu class
|
||||
|
||||
Handles all types of blog menu
|
||||
"""
|
||||
name = _('Blog menu')
|
||||
|
||||
def get_nodes(self, request):
|
||||
"""
|
||||
Generates the nodelist
|
||||
|
||||
:param request:
|
||||
:return: list of nodes
|
||||
"""
|
||||
nodes = []
|
||||
|
||||
language = get_language_from_request(request, check_path=True)
|
||||
|
@ -40,9 +53,12 @@ class BlogCategoryMenu(CMSAttachMenu):
|
|||
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)
|
||||
'{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)
|
||||
|
||||
|
@ -57,10 +73,10 @@ class BlogCategoryMenu(CMSAttachMenu):
|
|||
if categories_menu:
|
||||
category = post.categories.first()
|
||||
if category:
|
||||
parent = '%s-%s' % (category.__class__.__name__, category.pk)
|
||||
post_id = '%s-%s' % (post.__class__.__name__, post.pk),
|
||||
parent = '{0}-{1}'.format(category.__class__.__name__, category.pk)
|
||||
post_id = '{0}-{1}'.format(post.__class__.__name__, post.pk),
|
||||
else:
|
||||
post_id = '%s-%s' % (post.__class__.__name__, post.pk),
|
||||
post_id = '{0}-{1}'.format(post.__class__.__name__, post.pk),
|
||||
if post_id:
|
||||
node = NavigationNode(
|
||||
post.get_title(),
|
||||
|
@ -75,7 +91,54 @@ class BlogCategoryMenu(CMSAttachMenu):
|
|||
menu_pool.register_menu(BlogCategoryMenu)
|
||||
|
||||
|
||||
class BlogNavModifier(Modifier):
|
||||
"""
|
||||
This navigation modifier makes sure that when
|
||||
a particular blog post is viewed,
|
||||
a corresponding category is selected in menu
|
||||
"""
|
||||
def modify(self, request, nodes, namespace, root_id, post_cut, breadcrumb):
|
||||
"""
|
||||
Actual modifier function
|
||||
:param request: request
|
||||
:param nodes: complete list of nodes
|
||||
:param namespace: Menu namespace
|
||||
:param root_id: eventual root_id
|
||||
:param post_cut: flag for modifier stage
|
||||
:param breadcrumb: flag for modifier stage
|
||||
:return: nodeslist
|
||||
"""
|
||||
app = None
|
||||
config = None
|
||||
if getattr(request, 'current_page', None) and request.current_page.application_urls:
|
||||
app = apphook_pool.get_apphook(request.current_page.application_urls)
|
||||
|
||||
if app and app.app_config:
|
||||
namespace = resolve(request.path).namespace
|
||||
config = app.get_config(namespace)
|
||||
if config and config.menu_structure != MENU_TYPE_CATEGORIES:
|
||||
return nodes
|
||||
if post_cut:
|
||||
return nodes
|
||||
current_post = getattr(request, get_setting('CURRENT_POST_IDENTIFIER'), None)
|
||||
category = None
|
||||
if current_post and current_post.__class__ == Post:
|
||||
category = current_post.categories.first()
|
||||
if not category:
|
||||
return nodes
|
||||
|
||||
for node in nodes:
|
||||
if '{0}-{1}'.format(category.__class__.__name__, category.pk) == node.id:
|
||||
node.selected = True
|
||||
return nodes
|
||||
|
||||
menu_pool.register_modifier(BlogNavModifier)
|
||||
|
||||
|
||||
def clear_menu_cache(**kwargs):
|
||||
"""
|
||||
Empty menu cache when saving categories
|
||||
"""
|
||||
menu_pool.clear(all=True)
|
||||
|
||||
post_save.connect(clear_menu_cache, sender=BlogCategory)
|
||||
|
|
|
@ -8,13 +8,17 @@ import filer.fields.image
|
|||
import meta_mixin.models
|
||||
import taggit_autosuggest.managers
|
||||
from django.conf import settings
|
||||
from django.db import models, migrations
|
||||
from django.db import migrations, models
|
||||
from filer.settings import FILER_IMAGE_MODEL
|
||||
|
||||
ACTUAL_FILER_IMAGE_MODEL = FILER_IMAGE_MODEL or 'filer.Image'
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
migrations.swappable_dependency(ACTUAL_FILER_IMAGE_MODEL),
|
||||
('cms', '__latest__'),
|
||||
('taggit', '__latest__'),
|
||||
('filer', '__latest__'),
|
||||
|
@ -90,7 +94,7 @@ class Migration(migrations.Migration):
|
|||
('author', models.ForeignKey(related_name='djangocms_blog_post_author', verbose_name='Author', blank=True, to=settings.AUTH_USER_MODEL, null=True)),
|
||||
('categories', models.ManyToManyField(related_name='blog_posts', verbose_name='category', to='djangocms_blog.BlogCategory')),
|
||||
('content', cms.models.fields.PlaceholderField(slotname='post_content', editable=False, to='cms.Placeholder', null=True)),
|
||||
('main_image', filer.fields.image.FilerImageField(related_name='djangocms_blog_post_image', verbose_name='Main image', blank=True, to='filer.Image', null=True)),
|
||||
('main_image', filer.fields.image.FilerImageField(related_name='djangocms_blog_post_image', verbose_name='Main image', blank=True, to=ACTUAL_FILER_IMAGE_MODEL, null=True)),
|
||||
('main_image_full', models.ForeignKey(related_name='djangocms_blog_post_full', verbose_name='Main image full', blank=True, to='cmsplugin_filer_image.ThumbnailOption', null=True)),
|
||||
('main_image_thumbnail', models.ForeignKey(related_name='djangocms_blog_post_thumbnail', verbose_name='Main image thumbnail', blank=True, to='cmsplugin_filer_image.ThumbnailOption', null=True)),
|
||||
('tags', taggit_autosuggest.managers.TaggableManager(to='taggit.Tag', through='taggit.TaggedItem', blank=True, help_text='A comma-separated list of tags.', verbose_name='Tags')),
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
import filer.fields.image
|
||||
import django.db.models.deletion
|
||||
import filer.fields.image
|
||||
from django.db import migrations, models
|
||||
from filer.settings import FILER_IMAGE_MODEL
|
||||
|
||||
ACTUAL_FILER_IMAGE_MODEL = FILER_IMAGE_MODEL or 'filer.Image'
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(ACTUAL_FILER_IMAGE_MODEL),
|
||||
('djangocms_blog', '0003_auto_20141201_2252'),
|
||||
]
|
||||
|
||||
|
@ -16,7 +20,7 @@ class Migration(migrations.Migration):
|
|||
migrations.AlterField(
|
||||
model_name='post',
|
||||
name='main_image',
|
||||
field=filer.fields.image.FilerImageField(related_name='djangocms_blog_post_image', on_delete=django.db.models.deletion.SET_NULL, verbose_name='Main image', blank=True, to='filer.Image', null=True),
|
||||
field=filer.fields.image.FilerImageField(related_name='djangocms_blog_post_image', on_delete=django.db.models.deletion.SET_NULL, verbose_name='Main image', blank=True, to=ACTUAL_FILER_IMAGE_MODEL, null=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AlterField(
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
import filer.fields.image
|
||||
import django.utils.timezone
|
||||
from django.conf import settings
|
||||
import djangocms_text_ckeditor.fields
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
import djangocms_text_ckeditor.fields
|
||||
import filer.fields.image
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
from filer.settings import FILER_IMAGE_MODEL
|
||||
|
||||
ACTUAL_FILER_IMAGE_MODEL = FILER_IMAGE_MODEL or 'filer.Image'
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('djangocms_blog', '0006_auto_20150214_1907'),
|
||||
migrations.swappable_dependency(ACTUAL_FILER_IMAGE_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
|
@ -99,7 +103,7 @@ class Migration(migrations.Migration):
|
|||
migrations.AlterField(
|
||||
model_name='post',
|
||||
name='main_image',
|
||||
field=filer.fields.image.FilerImageField(on_delete=django.db.models.deletion.SET_NULL, blank=True, verbose_name='main image', to='filer.Image', related_name='djangocms_blog_post_image', null=True),
|
||||
field=filer.fields.image.FilerImageField(on_delete=django.db.models.deletion.SET_NULL, blank=True, verbose_name='main image', to=ACTUAL_FILER_IMAGE_MODEL, related_name='djangocms_blog_post_image', null=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AlterField(
|
||||
|
|
|
@ -4,37 +4,9 @@ from __future__ import unicode_literals
|
|||
import aldryn_apphooks_config.fields
|
||||
import app_data.fields
|
||||
import djangocms_text_ckeditor.fields
|
||||
from cms.models import Page
|
||||
from cms.utils.i18n import get_language_list
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
def forwards(apps, schema_editor):
|
||||
BlogConfig = apps.get_model('djangocms_blog', 'BlogConfig')
|
||||
BlogConfigTranslation = apps.get_model('djangocms_blog', 'BlogConfigTranslation')
|
||||
Post = apps.get_model('djangocms_blog', 'Post')
|
||||
BlogCategory = apps.get_model('djangocms_blog', 'BlogCategory')
|
||||
GenericBlogPlugin = apps.get_model('djangocms_blog', 'GenericBlogPlugin')
|
||||
LatestPostsPlugin = apps.get_model('djangocms_blog', 'LatestPostsPlugin')
|
||||
AuthorEntriesPlugin = apps.get_model('djangocms_blog', 'AuthorEntriesPlugin')
|
||||
config = None
|
||||
for page in Page.objects.drafts().filter(application_urls='BlogApp'):
|
||||
config = BlogConfig.objects.create(namespace=page.application_namespace)
|
||||
for lang in get_language_list():
|
||||
title = page.get_title(lang)
|
||||
translation = BlogConfigTranslation.objects.create(language_code=lang, master_id=config.pk, app_title=title)
|
||||
if config:
|
||||
for model in (Post, BlogCategory, GenericBlogPlugin, LatestPostsPlugin, AuthorEntriesPlugin):
|
||||
for item in model.objects.all():
|
||||
item.app_config = config
|
||||
item.save()
|
||||
|
||||
|
||||
def backwards(apps, schema_editor):
|
||||
# No need for backward data migration
|
||||
pass
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
|
@ -120,5 +92,4 @@ class Migration(migrations.Migration):
|
|||
name='sites',
|
||||
field=models.ManyToManyField(to='sites.Site', help_text='Select sites in which to show the post. If none is set it will be visible in all the configured sites.', blank=True, verbose_name='Site(s)'),
|
||||
),
|
||||
migrations.RunPython(forwards, backwards)
|
||||
]
|
||||
|
|
43
djangocms_blog/migrations/0014_auto_20160215_1331.py
Normal file
43
djangocms_blog/migrations/0014_auto_20160215_1331.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from cms.models import Page
|
||||
from cms.utils.i18n import get_language_list
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
def forwards(apps, schema_editor):
|
||||
BlogConfig = apps.get_model('djangocms_blog', 'BlogConfig')
|
||||
BlogConfigTranslation = apps.get_model('djangocms_blog', 'BlogConfigTranslation')
|
||||
Post = apps.get_model('djangocms_blog', 'Post')
|
||||
BlogCategory = apps.get_model('djangocms_blog', 'BlogCategory')
|
||||
GenericBlogPlugin = apps.get_model('djangocms_blog', 'GenericBlogPlugin')
|
||||
LatestPostsPlugin = apps.get_model('djangocms_blog', 'LatestPostsPlugin')
|
||||
AuthorEntriesPlugin = apps.get_model('djangocms_blog', 'AuthorEntriesPlugin')
|
||||
config = None
|
||||
for page in Page.objects.drafts().filter(application_urls='BlogApp'):
|
||||
config, created = BlogConfig.objects.get_or_create(namespace=page.application_namespace)
|
||||
if not BlogConfigTranslation.objects.exists():
|
||||
for lang in get_language_list():
|
||||
title = page.get_title(lang)
|
||||
translation = BlogConfigTranslation.objects.create(language_code=lang, master_id=config.pk, app_title=title)
|
||||
if config:
|
||||
for model in (Post, BlogCategory, GenericBlogPlugin, LatestPostsPlugin, AuthorEntriesPlugin):
|
||||
for item in model.objects.filter(app_config__isnull=True):
|
||||
item.app_config = config
|
||||
item.save()
|
||||
|
||||
|
||||
def backwards(apps, schema_editor):
|
||||
# No need for backward data migration
|
||||
pass
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('djangocms_blog', '0013_auto_20160201_2235'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(forwards, backwards),
|
||||
]
|
2
setup.py
2
setup.py
|
@ -27,7 +27,7 @@ setup(
|
|||
],
|
||||
include_package_data=True,
|
||||
install_requires=[
|
||||
'django-parler>=1.2',
|
||||
'django-parler>=1.5',
|
||||
'django-cms>3.0.11',
|
||||
'django-taggit>=0.12.2',
|
||||
'django-filer',
|
||||
|
|
|
@ -29,6 +29,7 @@ class MenuTest(BaseTest):
|
|||
self.cats.append(cat)
|
||||
|
||||
activate('en')
|
||||
menu_pool.clear(all=True)
|
||||
menu_pool.discover_menus()
|
||||
# All cms menu modifiers should be removed from menu_pool.modifiers
|
||||
# so that they do not interfere with our menu nodes
|
||||
|
@ -139,22 +140,55 @@ class MenuTest(BaseTest):
|
|||
(PostDetailView, 'slug', posts[0], posts[0].categories.first()),
|
||||
(CategoryEntriesView, 'category', self.cats[2], self.cats[2])
|
||||
)
|
||||
self.app_config_1.app_data.config.menu_structure = MENU_TYPE_COMPLETE
|
||||
self.app_config_1.save()
|
||||
for view_cls, kwarg, obj, cat in tests:
|
||||
request = self.get_page_request(pages[1], self.user, path=obj.get_absolute_url())
|
||||
with smart_override('en'):
|
||||
with switch_language(obj, 'en'):
|
||||
request = self.get_page_request(
|
||||
pages[1], self.user, path=obj.get_absolute_url()
|
||||
)
|
||||
cache.clear()
|
||||
menu_pool.clear(all=True)
|
||||
view_obj = view_cls()
|
||||
view_obj.request = request
|
||||
view_obj.namespace, view_obj.config = get_app_instance(request)
|
||||
view_obj.app_config = self.app_config_1
|
||||
view_obj.kwargs = {kwarg: obj.slug}
|
||||
view_obj.get(request)
|
||||
view_obj.get_context_data()
|
||||
# check if selected menu node points to cat
|
||||
nodes = menu_pool.get_nodes(request)
|
||||
found = False
|
||||
found = []
|
||||
for node in nodes:
|
||||
if node.selected:
|
||||
self.assertEqual(node.url, obj.get_absolute_url())
|
||||
found = True
|
||||
break
|
||||
self.assertTrue(found)
|
||||
found.append(node.get_absolute_url())
|
||||
self.assertTrue(obj.get_absolute_url() in found)
|
||||
|
||||
self.app_config_1.app_data.config.menu_structure = MENU_TYPE_CATEGORIES
|
||||
self.app_config_1.save()
|
||||
for view_cls, kwarg, obj, cat in tests:
|
||||
with smart_override('en'):
|
||||
with switch_language(obj, 'en'):
|
||||
request = self.get_page_request(
|
||||
pages[1], self.user, path=obj.get_absolute_url()
|
||||
)
|
||||
cache.clear()
|
||||
menu_pool.clear(all=True)
|
||||
view_obj = view_cls()
|
||||
view_obj.request = request
|
||||
view_obj.namespace, view_obj.config = get_app_instance(request)
|
||||
view_obj.app_config = self.app_config_1
|
||||
view_obj.kwargs = {kwarg: obj.slug}
|
||||
view_obj.get(request)
|
||||
view_obj.get_context_data()
|
||||
# check if selected menu node points to cat
|
||||
nodes = menu_pool.get_nodes(request)
|
||||
found = []
|
||||
for node in nodes:
|
||||
if node.selected:
|
||||
found.append(node.get_absolute_url())
|
||||
self.assertTrue(cat.get_absolute_url() in found)
|
||||
|
||||
self.app_config_1.app_data.config.menu_structure = MENU_TYPE_COMPLETE
|
||||
self.app_config_1.save()
|
||||
|
|
|
@ -34,6 +34,8 @@ class AdminTest(BaseTest):
|
|||
admin.autodiscover()
|
||||
|
||||
def test_admin_post_views(self):
|
||||
self.get_pages()
|
||||
|
||||
post_admin = admin.site._registry[Post]
|
||||
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, '<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):
|
||||
post_admin = admin.site._registry[BlogConfig]
|
||||
request = self.get_page_request('/', self.user, r'/en/blog/', edit=False)
|
||||
|
@ -67,7 +91,7 @@ class AdminTest(BaseTest):
|
|||
for fieldname in BlogConfigForm.base_fields:
|
||||
self.assertContains(response, 'id="id_config-%s"' % fieldname)
|
||||
self.assertContains(response, '<input id="id_config-og_app_id" maxlength="200" name="config-og_app_id" type="text" />')
|
||||
self.assertContains(response, '<input class="vTextField" id="id_namespace" maxlength="100" name="namespace" type="text" value="sample_app" />')
|
||||
self.assertContains(response, 'sample_app')
|
||||
|
||||
def test_admin_category_views(self):
|
||||
post_admin = admin.site._registry[BlogCategory]
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
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.utils.encoding import force_text
|
||||
|
||||
from djangocms_blog.models import BLOG_CURRENT_POST_IDENTIFIER
|
||||
|
||||
|
@ -20,9 +21,39 @@ class ToolbarTest(BaseTest):
|
|||
pages = self.get_pages()
|
||||
request = self.get_page_request(pages[0], self.user, r'/en/blog/', edit=True)
|
||||
setattr(request, BLOG_CURRENT_POST_IDENTIFIER, posts[0])
|
||||
|
||||
posts[0].publish = False
|
||||
posts[0].save()
|
||||
toolbar = CMSToolbar(request)
|
||||
toolbar.populate()
|
||||
toolbar.post_template_populate()
|
||||
toolbar.get_left_items()
|
||||
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_add'))), 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…
Add table
Reference in a new issue