Skip to content

Commit

Permalink
Generate valid slug in wizard if the given one is taken
Browse files Browse the repository at this point in the history
  • Loading branch information
yakky committed Jan 19, 2018
1 parent 5ba20ed commit f71f1d0
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 13 deletions.
26 changes: 24 additions & 2 deletions djangocms_blog/cms_wizards.py
Expand Up @@ -8,17 +8,22 @@
from cms.wizards.wizard_pool import AlreadyRegisteredException, wizard_pool
from django import forms
from django.conf import settings
from django.utils.text import slugify
from django.utils.translation import ugettext_lazy as _

from .cms_appconfig import BlogConfig
from .fields import slugify
from .forms import PostAdminFormBase
from .models import Post


class PostWizardForm(PostAdminFormBase):
default_appconfig = None

slug = forms.SlugField(
label=_('Slug'), max_length=767, required=False,
help_text=_('Leave empty for automatic slug, or override as required.'),
)

def __init__(self, *args, **kwargs):
if 'initial' not in kwargs or not kwargs.get('initial', False):
kwargs['initial'] = {}
Expand All @@ -36,7 +41,7 @@ def __init__(self, *args, **kwargs):

class Meta:
model = Post
fields = ['app_config', 'title', 'abstract', 'categories']
fields = ['app_config', 'title', 'slug', 'abstract', 'categories']

class Media:
js = ('admin/js/jquery.js', 'admin/js/jquery.init.js',)
Expand All @@ -45,6 +50,23 @@ def save(self, commit=True):
self.instance._set_default_author(get_current_user())
return super(PostWizardForm, self).save(commit)

def clean_slug(self):
"""
Generate a valid slug, in case the given one is taken
"""
source = self.cleaned_data.get('slug', '')
lang_choice = self.language_code
if not source:
source = slugify(self.cleaned_data.get('title', ''))
qs = Post._default_manager.active_translations(lang_choice).language(lang_choice)
used = list(qs.values_list('translations__slug', flat=True))
slug = source
i = 1
while slug in used:
slug = '%s-%s' % (source, i)
i += 1
return slug


class PostWizard(Wizard):
pass
Expand Down
12 changes: 12 additions & 0 deletions djangocms_blog/fields.py
@@ -1,4 +1,9 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, unicode_literals

import django
from django.db.models import SlugField
from django.utils.text import slugify as django_slugify

__all__ = ['AutoSlugField']

Expand All @@ -7,3 +12,10 @@ class AutoSlugField(SlugField):
def __init__(self, *args, **kwargs):
self.allow_unicode = kwargs.pop('allow_unicode', False)
super(SlugField, self).__init__(*args, **kwargs)


def slugify(base):
if django.VERSION >= (1, 9):
return django_slugify(base, allow_unicode=True)
else:
return django_slugify(base)
18 changes: 7 additions & 11 deletions djangocms_blog/models.py
Expand Up @@ -3,7 +3,6 @@

import hashlib

import django
from aldryn_apphooks_config.fields import AppHookConfigField
from aldryn_apphooks_config.managers.parler import AppHookConfigTranslatableManager
from cms.models import CMSPlugin, PlaceholderField
Expand All @@ -19,7 +18,6 @@
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.text import slugify
from django.utils.translation import get_language, ugettext_lazy as _
from djangocms_text_ckeditor.fields import HTMLField
from filer.fields.image import FilerImageField
Expand All @@ -30,7 +28,7 @@
from taggit_autosuggest.managers import TaggableManager

from .cms_appconfig import BlogConfig
from .fields import AutoSlugField
from .fields import AutoSlugField, slugify
from .managers import GenericDateTaggedManager
from .settings import get_setting

Expand All @@ -47,7 +45,6 @@
ThumbnailOption._meta.app_label, ThumbnailOption.__name__
)


try:
from knocker.mixins import KnockerModel
except ImportError:
Expand Down Expand Up @@ -315,10 +312,7 @@ def save(self, *args, **kwargs):
if self.publish and self.date_published is None:
self.date_published = timezone.now()
if not self.slug and self.title:
if django.VERSION >= (1, 9):
self.slug = slugify(self.title, allow_unicode=True)
else:
self.slug = slugify(self.title)
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)

def save_translation(self, translation, *args, **kwargs):
Expand Down Expand Up @@ -349,9 +343,12 @@ def get_absolute_url(self, lang=None):
if '<day>' in urlconf:
kwargs['day'] = '%02d' % current_date.day
if '<slug>' in urlconf:
kwargs['slug'] = self.safe_translation_getter('slug', language_code=lang, any_language=True) # NOQA
kwargs['slug'] = self.safe_translation_getter(
'slug', language_code=lang, any_language=True
) # NOQA
if '<category>' in urlconf:
kwargs['category'] = category.safe_translation_getter('slug', language_code=lang, any_language=True) # NOQA
kwargs['category'] = category.safe_translation_getter(
'slug', language_code=lang, any_language=True) # NOQA
return reverse('%s:post-detail' % self.app_config.namespace, kwargs=kwargs)

def get_title(self):
Expand Down Expand Up @@ -555,7 +552,6 @@ def get_authors(self):

@python_2_unicode_compatible
class GenericBlogPlugin(BasePostPlugin):

class Meta:
abstract = False

Expand Down
45 changes: 45 additions & 0 deletions tests/test_wizards.py
Expand Up @@ -82,6 +82,51 @@ def test_wizard_init(self):
instance = form.save()
self.assertEqual(instance.author, self.user_normal)

def test_wizard_duplicate_slug(self):
from cms.utils.permissions import current_user
from cms.wizards.wizard_pool import wizard_pool
from djangocms_blog.models import Post
self.get_pages()
cat_2 = BlogCategory.objects.create(name='category 1 - blog 2', app_config=self.app_config_2)

with current_user(self.user_staff):
wiz = None
for wiz in wizard_pool.get_entries():
if wiz.model == Post and wiz.title == 'New Blog':
break
form = wiz.form(data={
'1-title': 'title article',
'1-abstract': 'abstract article',
'1-categories': [self.category_1.pk],
}, prefix=1)
self.assertEqual(form.default_appconfig, self.app_config_1.pk)
self.assertTrue(form.is_valid())
instance1 = form.save()
self.assertEqual(instance1.slug, 'title-article')

form = wiz.form(data={
'1-title': 'title article',
'1-abstract': 'abstract article',
'1-categories': [self.category_1.pk],
}, prefix=1)
self.assertEqual(form.default_appconfig, self.app_config_1.pk)
self.assertTrue(form.is_valid())
instance2 = form.save()
self.assertEqual(instance2.slug, 'title-article-1')

for wiz in wizard_pool.get_entries():
if wiz.model == Post and wiz.title == 'New Article':
break
form = wiz.form(data={
'1-title': 'title article',
'1-abstract': 'abstract article',
'1-categories': [cat_2.pk],
}, prefix=1)
self.assertEqual(form.default_appconfig, self.app_config_2.pk)
self.assertTrue(form.is_valid())
instance3 = form.save()
self.assertEqual(instance3.slug, 'title-article-2')

def test_wizard_init_categories_check(self):
from cms.utils.permissions import current_user
from cms.wizards.wizard_pool import wizard_pool
Expand Down

0 comments on commit f71f1d0

Please sign in to comment.