Merge pull request #287 from nephila/feature/multisite-filters

WiP: Multisite filters
This commit is contained in:
Iacopo Spalletti 2016-06-28 22:53:39 +02:00 committed by GitHub
commit ecfe85fb1f
17 changed files with 417 additions and 112 deletions

View file

@ -10,7 +10,11 @@ History
* Dropped support for Django<1.8, django CMS<3.2. * Dropped support for Django<1.8, django CMS<3.2.
* Added liveblog application. * Added liveblog application.
* Refactored plugin filters: by default only data for current site are now shown.
* Added global and per site posts count to BlogCategory.
* Added option to hide empty categories from menu.
* Added standalone documentation at https://djangocms-blog.readthedocs.io. * Added standalone documentation at https://djangocms-blog.readthedocs.io.
* Enabled cached version of BlogLatestEntriesPlugin.
****************** ******************
0.8.5 (2016-06-26) 0.8.5 (2016-06-26)

View file

@ -96,6 +96,11 @@ HELPER_SETTINGS = dict(
HAYSTACK_CONNECTIONS={ HAYSTACK_CONNECTIONS={
'default': {} 'default': {}
}, },
CACHES={
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
}
}
) )
try: try:

View file

@ -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',)
}), }),

View file

@ -66,6 +66,11 @@ 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=get_setting('MENU_EMPTY_CATEGORIES'),
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'),

View file

@ -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)

View file

@ -5,6 +5,8 @@ import os.path
from cms.plugin_base import CMSPluginBase from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool from cms.plugin_pool import plugin_pool
from django.contrib.sites.shortcuts import get_current_site
from django.db import models
from .forms import LatestEntriesForm from .forms import LatestEntriesForm
from .models import AuthorEntriesPlugin, BlogCategory, GenericBlogPlugin, LatestPostsPlugin, Post from .models import AuthorEntriesPlugin, BlogCategory, GenericBlogPlugin, LatestPostsPlugin, Post
@ -36,7 +38,7 @@ class BlogLatestEntriesPlugin(BlogPlugin):
def render(self, context, instance, placeholder): def render(self, context, instance, placeholder):
context = super(BlogLatestEntriesPlugin, self).render(context, instance, placeholder) context = super(BlogLatestEntriesPlugin, self).render(context, instance, placeholder)
context['posts_list'] = instance.get_posts(context['request']) context['posts_list'] = instance.get_posts(context['request'], published_only=False)
context['TRUNCWORDS_COUNT'] = get_setting('POSTS_LIST_TRUNCWORDS_COUNT') context['TRUNCWORDS_COUNT'] = get_setting('POSTS_LIST_TRUNCWORDS_COUNT')
return context return context
@ -45,7 +47,7 @@ class BlogLatestEntriesPluginCached(BlogPlugin):
""" """
Cached plugin which returns the latest published posts Cached plugin which returns the latest published posts
""" """
name = get_setting('LATEST_ENTRIES_PLUGIN_NAME') name = get_setting('LATEST_ENTRIES_PLUGIN_NAME_CACHED')
model = LatestPostsPlugin model = LatestPostsPlugin
form = LatestEntriesForm form = LatestEntriesForm
filter_horizontal = ('categories',) filter_horizontal = ('categories',)
@ -54,7 +56,7 @@ class BlogLatestEntriesPluginCached(BlogPlugin):
def render(self, context, instance, placeholder): def render(self, context, instance, placeholder):
context = super(BlogLatestEntriesPluginCached, self).render(context, instance, placeholder) context = super(BlogLatestEntriesPluginCached, self).render(context, instance, placeholder)
context['posts_list'] = instance.get_posts() context['posts_list'] = instance.get_posts(context['request'])
context['TRUNCWORDS_COUNT'] = get_setting('POSTS_LIST_TRUNCWORDS_COUNT') context['TRUNCWORDS_COUNT'] = get_setting('POSTS_LIST_TRUNCWORDS_COUNT')
return context return context
@ -80,11 +82,8 @@ class BlogTagsPlugin(BlogPlugin):
def render(self, context, instance, placeholder): def render(self, context, instance, placeholder):
context = super(BlogTagsPlugin, self).render(context, instance, placeholder) context = super(BlogTagsPlugin, self).render(context, instance, placeholder)
qs = Post._default_manager qs = instance.post_queryset(context['request'])
qs_post = qs context['tags'] = Post.objects.tag_cloud(queryset=qs.published())
if instance.app_config:
qs_post = qs_post.namespace(instance.app_config.namespace)
context['tags'] = qs.tag_cloud(queryset=qs_post.published())
return context return context
@ -96,10 +95,15 @@ class BlogCategoryPlugin(BlogPlugin):
def render(self, context, instance, placeholder): def render(self, context, instance, placeholder):
context = super(BlogCategoryPlugin, self).render(context, instance, placeholder) context = super(BlogCategoryPlugin, self).render(context, instance, placeholder)
qs = BlogCategory._default_manager qs = BlogCategory.objects.language().active_translations()
if instance.app_config: if instance.app_config:
qs = qs.namespace(instance.app_config.namespace) qs = qs.namespace(instance.app_config.namespace)
context['categories'] = qs if instance.current_site:
site = get_current_site(context['request'])
qs = qs.filter(
models.Q(blog_posts__sites__isnull=True) | models.Q(blog_posts__sites=site.pk)
)
context['categories'] = qs.distinct()
return context return context
@ -111,15 +115,13 @@ class BlogArchivePlugin(BlogPlugin):
def render(self, context, instance, placeholder): def render(self, context, instance, placeholder):
context = super(BlogArchivePlugin, self).render(context, instance, placeholder) context = super(BlogArchivePlugin, self).render(context, instance, placeholder)
qs = Post._default_manager qs = instance.post_queryset(context['request'])
qs_post = qs context['dates'] = Post.objects.get_months(queryset=qs.published())
if instance.app_config:
qs_post = qs.namespace(instance.app_config.namespace)
context['dates'] = qs.get_months(queryset=qs_post.published())
return context return context
plugin_pool.register_plugin(BlogLatestEntriesPlugin) plugin_pool.register_plugin(BlogLatestEntriesPlugin)
plugin_pool.register_plugin(BlogLatestEntriesPluginCached)
plugin_pool.register_plugin(BlogAuthorPostsPlugin) plugin_pool.register_plugin(BlogAuthorPostsPlugin)
plugin_pool.register_plugin(BlogTagsPlugin) plugin_pool.register_plugin(BlogTagsPlugin)
plugin_pool.register_plugin(BlogArchivePlugin) plugin_pool.register_plugin(BlogArchivePlugin)

View file

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, unicode_literals from __future__ import absolute_import, print_function, unicode_literals
default_app_config = 'djangocms_blog.liveblog.apps.LiveBlogAppConfig' default_app_config = 'djangocms_blog.liveblog.apps.LiveBlogAppConfig'

View file

@ -56,8 +56,10 @@ class TaggedFilterItem(object):
queryset = self.tag_list(other_model, queryset) queryset = self.tag_list(other_model, queryset)
return queryset.values('slug') return queryset.values('slug')
def tag_cloud(self, other_model=None, queryset=None, published=True): def tag_cloud(self, other_model=None, queryset=None, published=True, on_site=False):
from taggit.models import TaggedItem from taggit.models import TaggedItem
if on_site:
queryset = queryset.on_site()
tag_ids = self._taglist(other_model, queryset) tag_ids = self._taglist(other_model, queryset)
kwargs = {} kwargs = {}
if published: if published:
@ -80,20 +82,25 @@ class GenericDateQuerySet(AppHookConfigTranslatableQueryset):
end_date_field = 'date_published_end' end_date_field = 'date_published_end'
publish_field = 'publish' publish_field = 'publish'
def on_site(self): def on_site(self, site=None):
if not site:
site = Site.objects.get_current()
return self.filter(models.Q(sites__isnull=True) | return self.filter(models.Q(sites__isnull=True) |
models.Q(sites=Site.objects.get_current().pk)) models.Q(sites=site.pk))
def published(self): def published(self, current_site=True):
queryset = self.published_future() queryset = self.published_future(current_site)
if self.start_date_field: if self.start_date_field:
return queryset.filter( return queryset.filter(
**{'%s__lte' % self.start_date_field: now()}) **{'%s__lte' % self.start_date_field: now()})
else: else:
return queryset return queryset
def published_future(self): def published_future(self, current_site=True):
if current_site:
queryset = self.on_site() queryset = self.on_site()
else:
queryset = self
if self.end_date_field: if self.end_date_field:
qfilter = ( qfilter = (
models.Q(**{'%s__gte' % self.end_date_field: now()}) | models.Q(**{'%s__gte' % self.end_date_field: now()}) |
@ -102,21 +109,29 @@ class GenericDateQuerySet(AppHookConfigTranslatableQueryset):
queryset = queryset.filter(qfilter) queryset = queryset.filter(qfilter)
return queryset.filter(**{self.publish_field: True}) return queryset.filter(**{self.publish_field: True})
def archived(self): def archived(self, current_site=True):
if current_site:
queryset = self.on_site() queryset = self.on_site()
else:
queryset = self
if self.end_date_field: if self.end_date_field:
qfilter = ( qfilter = (
models.Q(**{'%s__lte' % self.end_date_field: now()}) | models.Q(**{'%s__lte' % self.end_date_field: now()})
models.Q(**{'%s__isnull' % self.end_date_field: False})
) )
queryset = queryset.filter(qfilter) queryset = queryset.filter(qfilter)
return queryset.filter(**{self.publish_field: True}) return queryset.filter(**{self.publish_field: True})
def available(self): def available(self, current_site=True):
if current_site:
return self.on_site().filter(**{self.publish_field: True}) return self.on_site().filter(**{self.publish_field: True})
else:
return self.filter(**{self.publish_field: True})
def filter_by_language(self, language): def filter_by_language(self, language, current_site=True):
if current_site:
return self.active_translations(language_code=language).on_site() return self.active_translations(language_code=language).on_site()
else:
return self.active_translations(language_code=language)
class GenericDateTaggedManager(TaggedFilterItem, AppHookConfigTranslatableManager): class GenericDateTaggedManager(TaggedFilterItem, AppHookConfigTranslatableManager):
@ -127,28 +142,29 @@ class GenericDateTaggedManager(TaggedFilterItem, AppHookConfigTranslatableManage
def get_queryset(self, *args, **kwargs): def get_queryset(self, *args, **kwargs):
return super(GenericDateTaggedManager, self).get_queryset(*args, **kwargs) return super(GenericDateTaggedManager, self).get_queryset(*args, **kwargs)
def published(self): def published(self, current_site=True):
return self.get_queryset().published() return self.get_queryset().published(current_site)
def available(self): def available(self, current_site=True):
return self.get_queryset().available() return self.get_queryset().available(current_site)
def archived(self): def archived(self, current_site=True):
return self.get_queryset().archived() return self.get_queryset().archived(current_site)
def published_future(self): def published_future(self, current_site=True):
return self.get_queryset().published_future() return self.get_queryset().published_future(current_site)
def filter_by_language(self, language): def filter_by_language(self, language, current_site=True):
return self.get_queryset().filter_by_language(language) return self.get_queryset().filter_by_language(language, current_site)
def get_months(self, queryset=None): def get_months(self, queryset=None, current_site=True):
""" """
Get months with aggregate count (how much posts is in the month). Get months with aggregate count (how much posts is in the month).
Results are ordered by date. Results are ordered by date.
""" """
if queryset is None: if queryset is None:
queryset = self.get_queryset() queryset = self.get_queryset()
if current_site:
queryset = queryset.on_site() queryset = queryset.on_site()
dates_qs = queryset.values_list(queryset.start_date_field, queryset.fallback_date_field) dates_qs = queryset.values_list(queryset.start_date_field, queryset.fallback_date_field)
dates = [] dates = []

View file

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-06-26 13:39
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('djangocms_blog', '0022_auto_20160605_2305'),
]
operations = [
migrations.AddField(
model_name='authorentriesplugin',
name='current_site',
field=models.BooleanField(default=True, help_text='Select items from the current site only', verbose_name='current site'),
),
migrations.AddField(
model_name='genericblogplugin',
name='current_site',
field=models.BooleanField(default=True, help_text='Select items from the current site only', verbose_name='current site'),
),
migrations.AddField(
model_name='latestpostsplugin',
name='current_site',
field=models.BooleanField(default=True, help_text='Select items from the current site only', verbose_name='current site'),
),
]

View file

@ -8,6 +8,7 @@ from aldryn_apphooks_config.managers.parler import AppHookConfigTranslatableMana
from cms.models import CMSPlugin, PlaceholderField from cms.models import CMSPlugin, PlaceholderField
from django.conf import settings as dj_settings from django.conf import settings as dj_settings
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.sites.shortcuts import get_current_site
from django.core.cache import cache from django.core.cache import cache
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.db import models from django.db import models
@ -15,6 +16,7 @@ from django.db.models.signals import post_save, pre_delete
from django.dispatch import receiver from django.dispatch import receiver
from django.utils import timezone from django.utils import timezone
from django.utils.encoding import force_bytes, force_text, python_2_unicode_compatible from django.utils.encoding import force_bytes, force_text, python_2_unicode_compatible
from django.utils.functional import cached_property
from django.utils.html import escape, strip_tags from django.utils.html import escape, strip_tags
from django.utils.text import slugify from django.utils.text import slugify
from django.utils.translation import get_language, ugettext_lazy as _ from django.utils.translation import get_language, ugettext_lazy as _
@ -76,9 +78,17 @@ class BlogCategory(TranslatableModel):
verbose_name = _('blog category') verbose_name = _('blog category')
verbose_name_plural = _('blog categories') verbose_name_plural = _('blog categories')
@property @cached_property
def linked_posts(self):
return self.blog_posts.namespace(self.app_config.namespace)
@cached_property
def count(self): def count(self):
return self.blog_posts.namespace(self.app_config.namespace).published().count() return self.linked_posts.published().count()
@cached_property
def count_all_sites(self):
return self.linked_posts.published(current_site=False).count()
def get_absolute_url(self, lang=None): def get_absolute_url(self, lang=None):
if not lang: if not lang:
@ -365,18 +375,24 @@ class BasePostPlugin(CMSPlugin):
app_config = AppHookConfigField( app_config = AppHookConfigField(
BlogConfig, null=True, verbose_name=_('app. config'), blank=True BlogConfig, null=True, verbose_name=_('app. config'), blank=True
) )
current_site = models.BooleanField(
_('current site'), default=True, help_text=_('Select items from the current site only')
)
class Meta: class Meta:
abstract = True abstract = True
def post_queryset(self, request=None): def post_queryset(self, request=None, published_only=True):
language = get_language() language = get_language()
posts = Post._default_manager posts = Post.objects
if self.app_config: if self.app_config:
posts = posts.namespace(self.app_config.namespace) posts = posts.namespace(self.app_config.namespace)
if self.current_site:
posts = posts.on_site(get_current_site(request))
posts = posts.active_translations(language_code=language) posts = posts.active_translations(language_code=language)
if not request or not getattr(request, 'toolbar', False) or not request.toolbar.edit_mode: if (published_only or not request or not getattr(request, 'toolbar', False) or
posts = posts.published() not request.toolbar.edit_mode):
posts = posts.published(current_site=self.current_site)
return posts.all() return posts.all()
@ -384,14 +400,14 @@ class BasePostPlugin(CMSPlugin):
class LatestPostsPlugin(BasePostPlugin): class LatestPostsPlugin(BasePostPlugin):
latest_posts = models.IntegerField(_('articles'), default=get_setting('LATEST_POSTS'), latest_posts = models.IntegerField(_('articles'), default=get_setting('LATEST_POSTS'),
help_text=_('The number of latests ' help_text=_('The number of latests '
u'articles to be displayed.')) 'articles to be displayed.'))
tags = TaggableManager(_('filter by tag'), blank=True, tags = TaggableManager(_('filter by tag'), blank=True,
help_text=_('Show only the blog articles tagged with chosen tags.'), help_text=_('Show only the blog articles tagged with chosen tags.'),
related_name='djangocms_blog_latest_post') related_name='djangocms_blog_latest_post')
categories = models.ManyToManyField('djangocms_blog.BlogCategory', blank=True, categories = models.ManyToManyField('djangocms_blog.BlogCategory', blank=True,
verbose_name=_('filter by category'), verbose_name=_('filter by category'),
help_text=_('Show only the blog articles tagged ' help_text=_('Show only the blog articles tagged '
u'with chosen categories.')) 'with chosen categories.'))
def __str__(self): def __str__(self):
return force_text(_('%s latest articles by tag') % self.latest_posts) return force_text(_('%s latest articles by tag') % self.latest_posts)
@ -402,8 +418,8 @@ class LatestPostsPlugin(BasePostPlugin):
for category in oldinstance.categories.all(): for category in oldinstance.categories.all():
self.categories.add(category) self.categories.add(category)
def get_posts(self, request): def get_posts(self, request, published_only=True):
posts = self.post_queryset(request) posts = self.post_queryset(request, published_only)
if self.tags.exists(): if self.tags.exists():
posts = posts.filter(tags__in=list(self.tags.all())) posts = posts.filter(tags__in=list(self.tags.all()))
if self.categories.exists(): if self.categories.exists():
@ -428,8 +444,8 @@ class AuthorEntriesPlugin(BasePostPlugin):
def copy_relations(self, oldinstance): def copy_relations(self, oldinstance):
self.authors = oldinstance.authors.all() self.authors = oldinstance.authors.all()
def get_posts(self, request): def get_posts(self, request, published_only=True):
posts = self.post_queryset(request) posts = self.post_queryset(request, published_only)
return posts[:self.latest_posts] return posts[:self.latest_posts]
def get_authors(self): def get_authors(self):
@ -439,7 +455,11 @@ class AuthorEntriesPlugin(BasePostPlugin):
qs = author.djangocms_blog_post_author qs = author.djangocms_blog_post_author
if self.app_config: if self.app_config:
qs = qs.namespace(self.app_config.namespace) qs = qs.namespace(self.app_config.namespace)
count = qs.filter(publish=True).count() if self.current_site:
qs = qs.published()
else:
qs = qs.published(current_site=False)
count = qs.count()
if count: if count:
author.count = count author.count = count
return authors return authors

View file

@ -58,6 +58,7 @@ def get_setting(name):
settings, 'BLOG_POSTS_LIST_TRUNCWORDS_COUNT', 100 settings, 'BLOG_POSTS_LIST_TRUNCWORDS_COUNT', 100
), ),
'BLOG_MENU_TYPES': MENU_TYPES, 'BLOG_MENU_TYPES': MENU_TYPES,
'BLOG_MENU_EMPTY_CATEGORIES': getattr(settings, 'MENU_EMPTY_CATEGORIES', True),
'BLOG_TYPE': getattr(settings, 'BLOG_TYPE', 'Article'), 'BLOG_TYPE': getattr(settings, 'BLOG_TYPE', 'Article'),
'BLOG_TYPES': meta_settings.OBJECT_TYPES, 'BLOG_TYPES': meta_settings.OBJECT_TYPES,
'BLOG_FB_TYPE': getattr(settings, 'BLOG_FB_TYPE', 'Article'), 'BLOG_FB_TYPE': getattr(settings, 'BLOG_FB_TYPE', 'Article'),
@ -113,6 +114,8 @@ def get_setting(name):
'BLOG_PLUGIN_MODULE_NAME': getattr(settings, 'BLOG_PLUGIN_MODULE_NAME', _('Blog')), 'BLOG_PLUGIN_MODULE_NAME': getattr(settings, 'BLOG_PLUGIN_MODULE_NAME', _('Blog')),
'BLOG_LATEST_ENTRIES_PLUGIN_NAME': getattr( 'BLOG_LATEST_ENTRIES_PLUGIN_NAME': getattr(
settings, 'BLOG_LATEST_ENTRIES_PLUGIN_NAME', _('Latest Blog Articles')), settings, 'BLOG_LATEST_ENTRIES_PLUGIN_NAME', _('Latest Blog Articles')),
'BLOG_LATEST_ENTRIES_PLUGIN_NAME_CACHED': getattr(
settings, 'BLOG_LATEST_ENTRIES_PLUGIN_NAME_CACHED', _('Latest Blog Articles - Cache')),
'BLOG_AUTHOR_POSTS_PLUGIN_NAME': getattr( 'BLOG_AUTHOR_POSTS_PLUGIN_NAME': getattr(
settings, 'BLOG_AUTHOR_POSTS_PLUGIN_NAME', _('Author Blog Articles')), settings, 'BLOG_AUTHOR_POSTS_PLUGIN_NAME', _('Author Blog Articles')),
'BLOG_TAGS_PLUGIN_NAME': getattr( 'BLOG_TAGS_PLUGIN_NAME': getattr(

View file

@ -11,6 +11,8 @@ Global Settings
detail; it's a dictionary with ``size``, ``crop`` and ``upscale`` keys; detail; it's a dictionary with ``size``, ``crop`` and ``upscale`` keys;
(default: ``{'size': '640x120', 'crop': True,'upscale': False}``) (default: ``{'size': '640x120', 'crop': True,'upscale': False}``)
* BLOG_PAGINATION: Number of post per page; (default: ``10``) * BLOG_PAGINATION: Number of post per page; (default: ``10``)
* BLOG_MENU_EMPTY_CATEGORIES: Flag to show / hide categories without posts
attached from the menu; (default: ``True``)
* BLOG_LATEST_POSTS: Default number of post in the **Latest post** plugin; * BLOG_LATEST_POSTS: Default number of post in the **Latest post** plugin;
(default: ``5``) (default: ``5``)
* BLOG_POSTS_LIST_TRUNCWORDS_COUNT: Default number of words shown for * BLOG_POSTS_LIST_TRUNCWORDS_COUNT: Default number of words shown for
@ -119,6 +121,7 @@ be used as defaults.
* Paginate sizePer-Apphook setting for BLOG_PAGINATION; * Paginate sizePer-Apphook setting for BLOG_PAGINATION;
* Template prefix: Alternative directory to load the blog templates from; * Template prefix: Alternative directory to load the blog templates from;
* Menu structure: Per-Apphook setting for BLOG_MENU_TYPE * Menu structure: Per-Apphook setting for BLOG_MENU_TYPE
* Show empty categories in menu: Per-Apphook setting for BLOG_MENU_EMPTY_CATEGORIES
* Sitemap changefreq: Per-Apphook setting for BLOG_SITEMAP_CHANGEFREQ_DEFAULT * Sitemap changefreq: Per-Apphook setting for BLOG_SITEMAP_CHANGEFREQ_DEFAULT
* Sitemap priority: Per-Apphook setting for BLOG_SITEMAP_PRIORITY_DEFAULT * Sitemap priority: Per-Apphook setting for BLOG_SITEMAP_PRIORITY_DEFAULT
* Object type: Per-Apphook setting for BLOG_TYPE * Object type: Per-Apphook setting for BLOG_TYPE

View file

@ -154,6 +154,8 @@ class BaseTest(BaseTestCase):
for post in Post.objects.all(): for post in Post.objects.all():
post.sites.clear() post.sites.clear()
post.tags.clear() post.tags.clear()
post.categories.clear()
cache.clear()
super(BaseTest, self).tearDown() super(BaseTest, self).tearDown()
def _get_category(self, data, category=None, lang='en'): def _get_category(self, data, category=None, lang='en'):

View file

@ -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

View file

@ -438,6 +438,33 @@ class AdminTest(BaseTest):
class ModelsTest(BaseTest): class ModelsTest(BaseTest):
def test_category_attributes(self):
posts = self.get_posts()
posts[0].publish = True
posts[0].save()
posts[1].publish = True
posts[1].save()
posts[1].sites.add(self.site_2)
new_category = BlogCategory.objects.create(
name='category 2', app_config=self.app_config_1
)
posts[1].categories.add(new_category)
with self.settings(SITE_ID=2):
self.assertEqual(new_category.count, 1)
self.assertEqual(self.category_1.count, 2)
self.assertEqual(new_category.count_all_sites, 1)
self.assertEqual(self.category_1.count_all_sites, 2)
# needed to clear cached properties
new_category = self.reload_model(new_category)
self.category_1 = self.reload_model(self.category_1)
with self.settings(SITE_ID=1):
self.assertEqual(new_category.count, 0)
self.assertEqual(self.category_1.count, 1)
self.assertEqual(new_category.count_all_sites, 1)
self.assertEqual(self.category_1.count_all_sites, 2)
def test_model_attributes(self): def test_model_attributes(self):
self.get_pages() self.get_pages()
@ -611,7 +638,10 @@ class ModelsTest(BaseTest):
# default queryset, published and unpublished posts # default queryset, published and unpublished posts
months = Post.objects.get_months() months = Post.objects.get_months()
for data in months: for data in months:
self.assertEqual(data['date'].date(), now().replace(year=now().year, month=now().month, day=1).date()) self.assertEqual(
data['date'].date(),
now().replace(year=now().year, month=now().month, day=1).date()
)
self.assertEqual(data['count'], 2) self.assertEqual(data['count'], 2)
# custom queryset, only published # custom queryset, only published
@ -619,9 +649,30 @@ class ModelsTest(BaseTest):
post1.save() post1.save()
months = Post.objects.get_months(Post.objects.published()) months = Post.objects.get_months(Post.objects.published())
for data in months: for data in months:
self.assertEqual(data['date'].date(), now().replace(year=now().year, month=now().month, day=1).date()) self.assertEqual(
data['date'].date(),
now().replace(year=now().year, month=now().month, day=1).date()
)
self.assertEqual(data['count'], 1) self.assertEqual(data['count'], 1)
# Move post to different site to filter it out
post2.sites.add(self.site_2)
months = Post.objects.get_months()
for data in months:
self.assertEqual(
data['date'].date(),
now().replace(year=now().year, month=now().month, day=1).date()
)
self.assertEqual(data['count'], 1)
months = Post.objects.get_months(current_site=False)
for data in months:
self.assertEqual(
data['date'].date(),
now().replace(year=now().year, month=now().month, day=1).date()
)
self.assertEqual(data['count'], 2)
post2.sites.clear()
self.assertEqual(len(Post.objects.available()), 1) self.assertEqual(len(Post.objects.available()), 1)
# If post is published but publishing date is in the future # If post is published but publishing date is in the future
@ -632,6 +683,7 @@ class ModelsTest(BaseTest):
self.assertEqual(len(Post.objects.published()), 1) self.assertEqual(len(Post.objects.published()), 1)
self.assertEqual(len(Post.objects.published_future()), 2) self.assertEqual(len(Post.objects.published_future()), 2)
self.assertEqual(len(Post.objects.archived()), 0) self.assertEqual(len(Post.objects.archived()), 0)
self.assertEqual(len(Post.objects.archived(current_site=False)), 0)
# If post is published but end publishing date is in the past # If post is published but end publishing date is in the past
post2.date_published = now().replace(year=now().year - 2, month=now().month, day=1) post2.date_published = now().replace(year=now().year - 2, month=now().month, day=1)
@ -640,10 +692,32 @@ class ModelsTest(BaseTest):
self.assertEqual(len(Post.objects.available()), 2) self.assertEqual(len(Post.objects.available()), 2)
self.assertEqual(len(Post.objects.published()), 1) self.assertEqual(len(Post.objects.published()), 1)
self.assertEqual(len(Post.objects.archived()), 1) self.assertEqual(len(Post.objects.archived()), 1)
self.assertEqual(len(Post.objects.archived(current_site=False)), 1)
# Move post to different site to filter it out
post2.sites.add(self.site_2)
self.assertEqual(len(Post.objects.archived()), 0)
self.assertEqual(len(Post.objects.archived(current_site=False)), 1)
self.assertEqual(len(Post.objects.available()), 1)
self.assertEqual(len(Post.objects.available(current_site=False)), 2)
self.assertEqual(len(Post.objects.published()), 1)
# publish post
post2.date_published = now() - timedelta(days=1)
post2.date_published_end = now() + timedelta(days=10)
post2.save()
self.assertEqual(len(Post.objects.archived()), 0)
self.assertEqual(len(Post.objects.archived(current_site=False)), 0)
self.assertEqual(len(Post.objects.available()), 1)
self.assertEqual(len(Post.objects.available(current_site=False)), 2)
self.assertEqual(len(Post.objects.published()), 1)
self.assertEqual(len(Post.objects.published(current_site=False)), 2)
# counting with language fallback enabled # counting with language fallback enabled
self._get_post(self._post_data[0]['it'], post1, 'it') self._get_post(self._post_data[0]['it'], post1, 'it')
self.assertEqual(len(Post.objects.filter_by_language('it')), 2) self.assertEqual(len(Post.objects.filter_by_language('it')), 1)
self.assertEqual(len(Post.objects.filter_by_language('it', current_site=False)), 2)
post2.sites.clear()
# No fallback # No fallback
parler.appsettings.PARLER_LANGUAGES['default']['hide_untranslated'] = True parler.appsettings.PARLER_LANGUAGES['default']['hide_untranslated'] = True
@ -706,7 +780,9 @@ class ModelsTest(BaseTest):
request = self.get_page_request('/', AnonymousUser(), r'/en/blog/', edit=False) request = self.get_page_request('/', AnonymousUser(), r'/en/blog/', edit=False)
request_auth = self.get_page_request('/', self.user_staff, r'/en/blog/', edit=False) request_auth = self.get_page_request('/', self.user_staff, r'/en/blog/', edit=False)
request_edit = self.get_page_request('/', self.user_staff, r'/en/blog/', edit=True) request_edit = self.get_page_request('/', self.user_staff, r'/en/blog/', edit=True)
plugin = add_plugin(post1.content, 'BlogLatestEntriesPlugin', language='en', app_config=self.app_config_1) plugin = add_plugin(
post1.content, 'BlogLatestEntriesPlugin', language='en', app_config=self.app_config_1
)
tag = Tag.objects.get(slug='tag-1') tag = Tag.objects.get(slug='tag-1')
plugin.tags.add(tag) plugin.tags.add(tag)
# unauthenticated users get no post # unauthenticated users get no post
@ -714,24 +790,33 @@ class ModelsTest(BaseTest):
# staff users not in edit mode get no post # staff users not in edit mode get no post
self.assertEqual(len(plugin.get_posts(request_auth)), 0) self.assertEqual(len(plugin.get_posts(request_auth)), 0)
# staff users in edit mode get the post # staff users in edit mode get the post
self.assertEqual(len(plugin.get_posts(request_edit)), 1) self.assertEqual(len(plugin.get_posts(request_edit, published_only=False)), 1)
post1.publish = True post1.publish = True
post1.save() post1.save()
self.assertEqual(len(plugin.get_posts(request)), 1) self.assertEqual(len(plugin.get_posts(request)), 1)
class ModelsTest2(BaseTest):
def test_copy_plugin_latest(self): def test_copy_plugin_latest(self):
post1 = self._get_post(self._post_data[0]['en']) post1 = self._get_post(self._post_data[0]['en'])
post2 = self._get_post(self._post_data[1]['en']) post2 = self._get_post(self._post_data[1]['en'])
tag1 = Tag.objects.create(name='tag 1') tag1 = Tag.objects.create(name='tag 1')
tag2 = Tag.objects.create(name='tag 2') tag2 = Tag.objects.create(name='tag 2')
plugin = add_plugin(post1.content, 'BlogLatestEntriesPlugin', language='en', app_config=self.app_config_1) plugin = add_plugin(
post1.content, 'BlogLatestEntriesPlugin', language='en', app_config=self.app_config_1
)
plugin.tags.add(tag1) plugin.tags.add(tag1)
plugin.tags.add(tag2) plugin.tags.add(tag2)
if CMS_30: if CMS_30:
plugins = list(post1.content.cmsplugin_set.filter(language='en').order_by('tree_id', 'level', 'position')) plugins = list(post1.content.cmsplugin_set.filter(language='en').order_by(
'tree_id', 'level', 'position'
))
else: else:
plugins = list(post1.content.cmsplugin_set.filter(language='en').order_by('path', 'depth', 'position')) plugins = list(post1.content.cmsplugin_set.filter(language='en').order_by(
'path', 'depth', 'position'
))
copy_plugins_to(plugins, post2.content) copy_plugins_to(plugins, post2.content)
new = downcast_plugins(post2.content.cmsplugin_set.all()) new = downcast_plugins(post2.content.cmsplugin_set.all())
self.assertEqual(set(new[0].tags.all()), set([tag1, tag2])) self.assertEqual(set(new[0].tags.all()), set([tag1, tag2]))
@ -741,7 +826,9 @@ class ModelsTest(BaseTest):
post1 = self._get_post(self._post_data[0]['en']) post1 = self._get_post(self._post_data[0]['en'])
post2 = self._get_post(self._post_data[1]['en']) post2 = self._get_post(self._post_data[1]['en'])
request = self.get_page_request('/', AnonymousUser(), r'/en/blog/', edit=False) request = self.get_page_request('/', AnonymousUser(), r'/en/blog/', edit=False)
plugin = add_plugin(post1.content, 'BlogAuthorPostsPlugin', language='en', app_config=self.app_config_1) plugin = add_plugin(
post1.content, 'BlogAuthorPostsPlugin', language='en', app_config=self.app_config_1
)
plugin.authors.add(self.user) plugin.authors.add(self.user)
self.assertEqual(len(plugin.get_posts(request)), 0) self.assertEqual(len(plugin.get_posts(request)), 0)
self.assertEqual(plugin.get_authors()[0].count, 0) self.assertEqual(plugin.get_authors()[0].count, 0)
@ -759,12 +846,18 @@ class ModelsTest(BaseTest):
def test_copy_plugin_author(self): def test_copy_plugin_author(self):
post1 = self._get_post(self._post_data[0]['en']) post1 = self._get_post(self._post_data[0]['en'])
post2 = self._get_post(self._post_data[1]['en']) post2 = self._get_post(self._post_data[1]['en'])
plugin = add_plugin(post1.content, 'BlogAuthorPostsPlugin', language='en', app_config=self.app_config_1) plugin = add_plugin(
post1.content, 'BlogAuthorPostsPlugin', language='en', app_config=self.app_config_1
)
plugin.authors.add(self.user) plugin.authors.add(self.user)
if CMS_30: if CMS_30:
plugins = list(post1.content.cmsplugin_set.filter(language='en').order_by('tree_id', 'level', 'position')) plugins = list(post1.content.cmsplugin_set.filter(language='en').order_by(
'tree_id', 'level', 'position'
))
else: else:
plugins = list(post1.content.cmsplugin_set.filter(language='en').order_by('path', 'depth', 'position')) plugins = list(post1.content.cmsplugin_set.filter(language='en').order_by(
'path', 'depth', 'position'
))
copy_plugins_to(plugins, post2.content) copy_plugins_to(plugins, post2.content)
new = downcast_plugins(post2.content.cmsplugin_set.all()) new = downcast_plugins(post2.content.cmsplugin_set.all())
self.assertEqual(set(new[0].authors.all()), set([self.user])) self.assertEqual(set(new[0].authors.all()), set([self.user]))
@ -797,13 +890,19 @@ class ModelsTest(BaseTest):
self.assertEqual(force_text(post1.categories.first()), 'category 1') self.assertEqual(force_text(post1.categories.first()), 'category 1')
plugin = add_plugin(post1.content, 'BlogAuthorPostsPlugin', language='en', app_config=self.app_config_1) plugin = add_plugin(
post1.content, 'BlogAuthorPostsPlugin', language='en', app_config=self.app_config_1
)
self.assertEqual(force_text(plugin.__str__()), '5 latest articles by author') self.assertEqual(force_text(plugin.__str__()), '5 latest articles by author')
plugin = add_plugin(post1.content, 'BlogLatestEntriesPlugin', language='en', app_config=self.app_config_1) plugin = add_plugin(
post1.content, 'BlogLatestEntriesPlugin', language='en', app_config=self.app_config_1
)
self.assertEqual(force_text(plugin.__str__()), '5 latest articles by tag') self.assertEqual(force_text(plugin.__str__()), '5 latest articles by tag')
plugin = add_plugin(post1.content, 'BlogArchivePlugin', language='en', app_config=self.app_config_1) plugin = add_plugin(
post1.content, 'BlogArchivePlugin', language='en', app_config=self.app_config_1
)
self.assertEqual(force_text(plugin.__str__()), 'generic blog plugin') self.assertEqual(force_text(plugin.__str__()), 'generic blog plugin')

View file

@ -5,6 +5,7 @@ import os.path
import re import re
from cms.api import add_plugin from cms.api import add_plugin
from django.contrib.sites.models import SITE_CACHE
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.utils.timezone import now from django.utils.timezone import now
from taggit.models import Tag from taggit.models import Tag
@ -16,6 +17,43 @@ from .base import BaseTest
class PluginTest(BaseTest): class PluginTest(BaseTest):
def test_plugin_latest_cached(self):
pages = self.get_pages()
posts = self.get_posts()
posts[0].tags.add('tag 1')
posts[0].publish = True
posts[0].save()
ph = pages[0].placeholders.get(slot='content')
plugin = add_plugin(
ph, 'BlogLatestEntriesPluginCached', language='en', app_config=self.app_config_1
)
context = self.get_plugin_context(pages[0], 'en', plugin, edit=True)
rendered = plugin.render_plugin(context, ph)
try:
self.assertTrue(rendered.find('cms_plugin-djangocms_blog-post-abstract-1') > -1)
except AssertionError:
self.assertTrue(rendered.find('cms-plugin-djangocms_blog-post-abstract-1') > -1)
self.assertTrue(rendered.find('<p>first line</p>') > -1)
self.assertTrue(rendered.find('<article id="post-first-post"') > -1)
self.assertTrue(rendered.find(posts[0].get_absolute_url()) > -1)
plugin_nocache = add_plugin(
ph, 'BlogLatestEntriesPlugin', language='en', app_config=self.app_config_1
)
with self.assertNumQueries(53):
plugin_nocache.render_plugin(context, ph)
with self.assertNumQueries(17):
rendered = plugin.render_plugin(context, ph)
try:
self.assertTrue(rendered.find('cms_plugin-djangocms_blog-post-abstract-1') > -1)
except AssertionError:
self.assertTrue(rendered.find('cms-plugin-djangocms_blog-post-abstract-1') > -1)
self.assertTrue(rendered.find('<p>first line</p>') > -1)
self.assertTrue(rendered.find('<article id="post-first-post"') > -1)
self.assertTrue(rendered.find(posts[0].get_absolute_url()) > -1)
def test_plugin_latest(self): def test_plugin_latest(self):
pages = self.get_pages() pages = self.get_pages()
posts = self.get_posts() posts = self.get_posts()
@ -24,7 +62,9 @@ class PluginTest(BaseTest):
posts[0].save() posts[0].save()
ph = pages[0].placeholders.get(slot='content') ph = pages[0].placeholders.get(slot='content')
plugin = add_plugin(ph, 'BlogLatestEntriesPlugin', language='en', app_config=self.app_config_1) plugin = add_plugin(
ph, 'BlogLatestEntriesPlugin', language='en', app_config=self.app_config_1
)
tag = Tag.objects.get(slug='tag-1') tag = Tag.objects.get(slug='tag-1')
plugin.tags.add(tag) plugin.tags.add(tag)
@ -34,7 +74,9 @@ class PluginTest(BaseTest):
self.assertTrue(rendered.find('cms_plugin-djangocms_blog-post-abstract-1') > -1) self.assertTrue(rendered.find('cms_plugin-djangocms_blog-post-abstract-1') > -1)
except AssertionError: except AssertionError:
self.assertTrue(rendered.find('cms-plugin-djangocms_blog-post-abstract-1') > -1) self.assertTrue(rendered.find('cms-plugin-djangocms_blog-post-abstract-1') > -1)
self.assertTrue(rendered.find(reverse('djangocms_blog:posts-tagged', kwargs={'tag': tag.slug})) > -1) self.assertTrue(
rendered.find(reverse('djangocms_blog:posts-tagged', kwargs={'tag': tag.slug})) > -1
)
self.assertTrue(rendered.find('<p>first line</p>') > -1) self.assertTrue(rendered.find('<p>first line</p>') > -1)
self.assertTrue(rendered.find('<article id="post-first-post"') > -1) self.assertTrue(rendered.find('<article id="post-first-post"') > -1)
self.assertTrue(rendered.find(posts[0].get_absolute_url()) > -1) self.assertTrue(rendered.find(posts[0].get_absolute_url()) > -1)
@ -45,7 +87,9 @@ class PluginTest(BaseTest):
category_2.save() category_2.save()
category_2.set_current_language('en') category_2.set_current_language('en')
posts[1].categories.add(category_2) posts[1].categories.add(category_2)
plugin = add_plugin(ph, 'BlogLatestEntriesPlugin', language='en', app_config=self.app_config_1) plugin = add_plugin(
ph, 'BlogLatestEntriesPlugin', language='en', app_config=self.app_config_1
)
plugin.categories.add(category_2) plugin.categories.add(category_2)
context = self.get_plugin_context(pages[0], 'en', plugin, edit=True) context = self.get_plugin_context(pages[0], 'en', plugin, edit=True)
@ -54,7 +98,10 @@ class PluginTest(BaseTest):
self.assertTrue(rendered.find('cms_plugin-djangocms_blog-post-abstract-2') > -1) self.assertTrue(rendered.find('cms_plugin-djangocms_blog-post-abstract-2') > -1)
except AssertionError: except AssertionError:
self.assertTrue(rendered.find('cms-plugin-djangocms_blog-post-abstract-2') > -1) self.assertTrue(rendered.find('cms-plugin-djangocms_blog-post-abstract-2') > -1)
self.assertTrue(rendered.find(reverse('djangocms_blog:posts-category', kwargs={'category': category_2.slug})) > -1) self.assertTrue(
rendered.find(reverse('djangocms_blog:posts-category',
kwargs={'category': category_2.slug})) > -1
)
self.assertTrue(rendered.find('<p>second post first line</p>') > -1) self.assertTrue(rendered.find('<p>second post first line</p>') > -1)
self.assertTrue(rendered.find('<article id="post-second-post"') > -1) self.assertTrue(rendered.find('<article id="post-second-post"') > -1)
self.assertTrue(rendered.find(posts[1].get_absolute_url()) > -1) self.assertTrue(rendered.find(posts[1].get_absolute_url()) > -1)
@ -77,6 +124,16 @@ class PluginTest(BaseTest):
self.assertEqual(casted_categories.tags.count(), 0) self.assertEqual(casted_categories.tags.count(), 0)
self.assertEqual(casted_categories.categories.count(), 1) self.assertEqual(casted_categories.categories.count(), 1)
posts[1].sites.add(self.site_2)
context = self.get_plugin_context(pages[0], 'en', plugin, edit=True)
rendered = plugin.render_plugin(context, ph)
self.assertFalse(rendered.find('<p>second post first line</p>') > -1)
posts[1].sites.remove(self.site_2)
context = self.get_plugin_context(pages[0], 'en', plugin, edit=True)
rendered = plugin.render_plugin(context, ph)
self.assertTrue(rendered.find('<p>second post first line</p>') > -1)
def test_plugin_tags(self): def test_plugin_tags(self):
pages = self.get_pages() pages = self.get_pages()
posts = self.get_posts() posts = self.get_posts()
@ -91,7 +148,9 @@ class PluginTest(BaseTest):
context = self.get_plugin_context(pages[0], 'en', plugin, edit=True) context = self.get_plugin_context(pages[0], 'en', plugin, edit=True)
rendered = plugin.render_plugin(context, ph) rendered = plugin.render_plugin(context, ph)
for tag in Tag.objects.all(): for tag in Tag.objects.all():
self.assertTrue(rendered.find(reverse('djangocms_blog:posts-tagged', kwargs={'tag': tag.slug})) > -1) self.assertTrue(rendered.find(
reverse('djangocms_blog:posts-tagged', kwargs={'tag': tag.slug})
) > -1)
if tag.slug == 'test-tag': if tag.slug == 'test-tag':
rf = '\s+%s\s+<span>\(\s+%s articles' % (tag.name, 2) rf = '\s+%s\s+<span>\(\s+%s articles' % (tag.name, 2)
else: else:
@ -99,21 +158,6 @@ class PluginTest(BaseTest):
rx = re.compile(rf) rx = re.compile(rf)
self.assertEqual(len(rx.findall(rendered)), 1) self.assertEqual(len(rx.findall(rendered)), 1)
def test_blog_category_plugin(self):
pages = self.get_pages()
posts = self.get_posts()
posts[0].publish = True
posts[0].save()
posts[1].publish = True
posts[1].save()
ph = pages[0].placeholders.get(slot='content')
plugin = add_plugin(ph, 'BlogCategoryPlugin', language='en', app_config=self.app_config_1)
plugin_class = plugin.get_plugin_class_instance()
context = self.get_plugin_context(pages[0], 'en', plugin, edit=True)
context = plugin_class.render(context, plugin, ph)
self.assertTrue(context['categories'])
self.assertEqual(list(context['categories']), [self.category_1])
def test_blog_archive_plugin(self): def test_blog_archive_plugin(self):
pages = self.get_pages() pages = self.get_pages()
posts = self.get_posts() posts = self.get_posts()
@ -199,3 +243,44 @@ class PluginTest2(BaseTest):
casted_authors, __ = new[0].get_plugin_instance() casted_authors, __ = new[0].get_plugin_instance()
self.assertEqual(casted_authors.authors.count(), 3) self.assertEqual(casted_authors.authors.count(), 3)
def test_blog_category_plugin(self):
pages = self.get_pages()
posts = self.get_posts()
self.category_1.set_current_language('en')
posts[0].publish = True
posts[0].save()
posts[1].publish = True
posts[1].save()
posts[1].sites.add(self.site_2)
new_category = BlogCategory.objects.create(
name='category 2', app_config=self.app_config_1
)
posts[1].categories.add(new_category)
ph = pages[0].placeholders.get(slot='content')
plugin = add_plugin(
ph, 'BlogCategoryPlugin', language='en', app_config=self.app_config_1
)
plugin_class = plugin.get_plugin_class_instance()
context = self.get_plugin_context(pages[0], 'en', plugin, edit=True)
context = plugin_class.render(context, plugin, ph)
self.assertTrue(context['categories'])
self.assertEqual(list(context['categories']), [self.category_1])
plugin.current_site = False
plugin.save()
context = plugin_class.render(context, plugin, ph)
self.assertEqual(list(context['categories']), [self.category_1, new_category])
plugin.current_site = True
plugin.save()
with self.settings(SITE_ID=2):
context = plugin_class.render(context, plugin, ph)
self.assertEqual(list(context['categories']), [self.category_1, new_category])
plugin.current_site = False
plugin.save()
with self.settings(SITE_ID=2):
context = plugin_class.render(context, plugin, ph)
self.assertEqual(list(context['categories']), [self.category_1, new_category])