Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/694 Content Hub Functionality #695

Open
wants to merge 27 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5d144b9
Add: Basic content hub feature: By category view with sorted categor…
fsbraun Nov 29, 2021
4aff4e4
Fix: flake8 errors
fsbraun Nov 29, 2021
cc70f3b
Fix: pep8 error in cms_appconfig
fsbraun Nov 29, 2021
1beb85a
Fix: space and quotation mark
fsbraun Nov 29, 2021
49b4cf2
Remove channels < 3 restriction to run tox tests
fsbraun Nov 29, 2021
5878bce
Fix: use_related initialization bug
fsbraun Nov 29, 2021
d42cde0
Add change file
fsbraun Nov 30, 2021
8f09ccd
Fix: avoid error if app config exists but no "use_related" field is …
fsbraun Nov 30, 2021
b830e09
Add: Documentation
fsbraun Nov 30, 2021
4ca34c1
Add: More documentation
fsbraun Nov 30, 2021
47cbd91
Add: allow_unicode=True for category sligs
fsbraun Dec 13, 2021
4139fa8
Add: allow_unicode for slugs controlled by new setting (default: True)
fsbraun Dec 14, 2021
1e179f0
Fix: flake8 lines too long
fsbraun Dec 14, 2021
dfae1ab
Add: Migrations
fsbraun Dec 14, 2021
94e0ecb
Fix: url reload after changing url config
fsbraun Dec 14, 2021
f9c1005
Fix: Added migration
fsbraun Dec 14, 2021
a7d7ad2
Fix: More DRY for per apphook urlconf
fsbraun Dec 14, 2021
1842356
Fix: Typos
fsbraun Dec 14, 2021
9c9e260
Fix: Tests
fsbraun Dec 15, 2021
49f0e0b
Try testing with adjusted req
fsbraun Dec 16, 2021
f490ae6
Fix: django<3.1 for docs
fsbraun Dec 16, 2021
1a38922
Test tests: excluded liveblog from test to check if tests run
fsbraun Dec 16, 2021
bf02512
Test: get tests running
fsbraun Dec 16, 2021
7bc1ef9
Fix: urlconf
fsbraun Jan 14, 2022
dc3342c
Fix: backwards compatibility of app confs
fsbraun May 2, 2022
bf9a2ff
Fix: category urls
fsbraun May 2, 2022
b181e93
Fix: category urls 2
fsbraun May 2, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/694.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add content hub functionality by adding a CategoryListView and apphook configuration for urls
1 change: 1 addition & 0 deletions cms_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ def gettext(s):


HELPER_SETTINGS = dict(
SECRET_KEY="secret",
ROOT_URLCONF="tests.test_utils.urls",
INSTALLED_APPS=[
"filer",
Expand Down
43 changes: 33 additions & 10 deletions djangocms_blog/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,34 @@ def queryset(self, request, queryset):
raise admin.options.IncorrectLookupParameters(e)


class BlogCategoryAdmin(ModelAppHookConfig, TranslatableAdmin):
class BlogCategoryAdmin(FrontendEditableAdminMixin, ModelAppHookConfig, TranslatableAdmin):
form = CategoryAdminForm
list_display = [
"name",
"parent",
"app_config",
"all_languages_column",
"priority",
]
fieldsets = (
(None, {
"fields": ("parent", "app_config", "name", "meta_description")
}),
(
_("Info"),
{
"fields": ("abstract", "priority",),
"classes": ("collapse",),
},
),
(
_("Images"),
{
"fields": ("main_image", "main_image_thumbnail", "main_image_full"),
"classes": ("collapse",),
},
),
)

def get_prepopulated_fields(self, request, obj=None):
app_config_default = self._app_config_select(request, obj)
Expand Down Expand Up @@ -122,7 +142,7 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin, ModelAppHookC
if apps.is_installed("djangocms_blog.liveblog"):
actions += ["enable_liveblog", "disable_liveblog"]
_fieldsets = [
(None, {"fields": ["title", "subtitle", "slug", "publish", ["categories", "app_config"]]}),
(None, {"fields": ["title", "subtitle", "slug", ["publish", "pinned"], ["categories", "app_config"]]}),
# left empty for sites, author and related fields
(None, {"fields": [[]]}),
(
Expand Down Expand Up @@ -381,14 +401,10 @@ def get_fieldsets(self, request, obj=None):

fsets = deepcopy(self._fieldsets)
related_posts = []
if config:
abstract = bool(config.use_abstract)
placeholder = bool(config.use_placeholder)
related = bool(config.use_related)
else:
abstract = get_setting("USE_ABSTRACT")
placeholder = get_setting("USE_PLACEHOLDER")
related = get_setting("USE_RELATED")
abstract = bool(getattr(config, "use_abstract", get_setting("USE_ABSTRACT")))
placeholder = bool(getattr(config, "use_placeholder", get_setting("USE_PLACEHOLDER")))
related = getattr(config, "use_related", get_setting("USE_RELATED"))
related = bool(int(related)) if isinstance(related, str) and related.isnumeric() else bool(related)
if related:
related_posts = self._get_available_posts(config)
if abstract:
Expand Down Expand Up @@ -480,6 +496,7 @@ def get_fieldsets(self, request, obj=None):
_("Layout"),
{
"fields": (
"config.urlconf",
"config.paginate_by",
"config.url_patterns",
"config.template_prefix",
Expand Down Expand Up @@ -550,6 +567,12 @@ def save_model(self, request, obj, form, change):
from menus.menu_pool import menu_pool

menu_pool.clear(all=True)
"""
Reload urls when changing url config
"""
if "config.urlconf" in form.changed_data:
from cms.signals.apphook import trigger_restart
trigger_restart()
return super().save_model(request, obj, form, change)


Expand Down
27 changes: 25 additions & 2 deletions djangocms_blog/cms_appconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,24 @@ class BlogConfigForm(AppDataForm):
label=_("Use abstract field"), required=False, initial=get_setting("USE_ABSTRACT")
)
#: Enable related posts (default: :ref:`USE_RELATED <USE_RELATED>`)
use_related = forms.BooleanField(
label=_("Enable related posts"), required=False, initial=get_setting("USE_RELATED")
use_related = forms.ChoiceField(
label=_("Enable related posts"),
required=False,
initial=int(get_setting("USE_RELATED")),
choices=(
(0, _("No")),
(1, _("Yes, from this blog config")),
(2, _("Yes, from this site")),
),
)
#: Adjust urlconf (default: :ref:`USE_RELATED <USE_RELATED>`)
urlconf = forms.ChoiceField(
label=_("URL config"),
required=False,
initial=get_setting("URLCONF") if isinstance(get_setting("URLCONF"), str) else get_setting("URLCONF")[0][0],
choices=(
[(get_setting("URLCONF"), "---")] if isinstance(get_setting("URLCONF"), str) else get_setting("URLCONF")
),
)
#: Set author by default (default: :ref:`AUTHOR_DEFAULT <AUTHOR_DEFAULT>`)
set_author = forms.BooleanField(
Expand Down Expand Up @@ -207,5 +223,12 @@ class BlogConfigForm(AppDataForm):
help_text=_("Emits a desktop notification -if enabled- when editing a published post"),
)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
"""Remove urlconf from form if no apphook-based url config is enabled"""
if isinstance(get_setting("URLCONF"), str):
self.fields["urlconf"].widget = forms.HiddenInput()
self.fields["urlconf"].label = "" # Admin otherwise displays label for hidden field


setup_config(BlogConfigForm, BlogConfig)
8 changes: 6 additions & 2 deletions djangocms_blog/cms_apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
@apphook_pool.register
class BlogApp(AutoCMSAppMixin, CMSConfigApp):
name = _("Blog")
_urls = [get_setting("URLCONF")]
_urls = [get_setting("URLCONF") if isinstance(get_setting("URLCONF"), str) else get_setting("URLCONF")[0][0]]
app_name = "djangocms_blog"
app_config = BlogConfig
_menus = [BlogCategoryMenu]
Expand All @@ -28,7 +28,11 @@ class BlogApp(AutoCMSAppMixin, CMSConfigApp):
}

def get_urls(self, page=None, language=None, **kwargs):
return [get_setting("URLCONF")]
urlconf = get_setting("URLCONF")
if page is None or not page.application_namespace or isinstance(urlconf, str):
return [urlconf] # Single urlconf
return [getattr(self.app_config.objects.get(namespace=page.application_namespace), "urlconf",
get_setting("URLCONF")[0][0])] # Default if no urlconf is configured

@property
def urls(self):
Expand Down
11 changes: 11 additions & 0 deletions djangocms_blog/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,15 @@ def available_categories(self):
return qs.namespace(self.app_config.namespace).active_translations()
return qs

@cached_property
def available_related_posts(self):
qs = Post.objects
if self.app_config:
qs = qs.active_translations()
if self.app_config.get("use_related", "0") == "1":
qs = qs.namespace(self.app_config.namespace)
return qs

def _post_clean_translation(self, translation):
# This is a quickfix for https://github.com/django-parler/django-parler/issues/236
# which needs to be fixed in parler
Expand All @@ -131,6 +140,8 @@ def __init__(self, *args, **kwargs):
if self.app_config and self.app_config.url_patterns == PERMALINK_TYPE_CATEGORY:
self.fields["categories"].required = True
self.fields["categories"].queryset = self.available_categories
if "related" in self.fields:
self.fields["related"].queryset = self.available_related_posts

if "app_config" in self.fields:
# Don't allow app_configs to be added here. The correct way to add an
Expand Down
49 changes: 49 additions & 0 deletions djangocms_blog/migrations/0040_auto_20211128_1503.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Generated by Django 3.0.14 on 2021-11-28 14:03

import django.db.models.deletion
import djangocms_text_ckeditor.fields
import filer.fields.image
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
# ('filer', '0014_folder_permission_choices'),
# migrations.swappable_dependency(settings.FILER_IMAGE_MODEL),
('djangocms_blog', '0039_auto_20200331_2227'),
]

operations = [
migrations.AddField(
model_name='blogcategory',
name='main_image',
field=filer.fields.image.FilerImageField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='djangocms_category_image', to=settings.FILER_IMAGE_MODEL, verbose_name='main image'),
),
migrations.AddField(
model_name='blogcategory',
name='main_image_full',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='djangocms_category_full', to='filer.ThumbnailOption', verbose_name='main image full'),
),
migrations.AddField(
model_name='blogcategory',
name='main_image_thumbnail',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='djangocms_category_thumbnail', to='filer.ThumbnailOption', verbose_name='main image thumbnail'),
),
migrations.AddField(
model_name='blogcategory',
name='priority',
field=models.IntegerField(blank=True, null=True, verbose_name='priority'),
),
migrations.AddField(
model_name='blogcategorytranslation',
name='abstract',
field=djangocms_text_ckeditor.fields.HTMLField(blank=True, default='', verbose_name='abstract'),
),
migrations.AddField(
model_name='post',
name='pinned',
field=models.IntegerField(blank=True, null=True, verbose_name='priority'),
),
]
32 changes: 32 additions & 0 deletions djangocms_blog/migrations/0041_auto_20211214_1137.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Generated by Django 3.0.14 on 2021-12-14 10:37

import django.db.models.expressions
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('djangocms_blog', '0040_auto_20211128_1503'),
]

operations = [
migrations.AlterModelOptions(
name='blogcategory',
options={'ordering': (django.db.models.expressions.OrderBy(django.db.models.expressions.F('priority'), nulls_last=True),), 'verbose_name': 'blog category', 'verbose_name_plural': 'blog categories'},
),
migrations.AlterModelOptions(
name='post',
options={'get_latest_by': 'date_published', 'ordering': (django.db.models.expressions.OrderBy(django.db.models.expressions.F('pinned'), nulls_last=True), '-date_published', '-date_created'), 'verbose_name': 'blog article', 'verbose_name_plural': 'blog articles'},
),
migrations.AlterField(
model_name='blogcategorytranslation',
name='slug',
field=models.SlugField(allow_unicode=True, blank=True, max_length=752, verbose_name='slug'),
),
migrations.AlterField(
model_name='post',
name='pinned',
field=models.IntegerField(blank=True, help_text='Pinned posts are shown in ascending order before unpinned ones. Leave blank for regular order by date.', null=True, verbose_name='pinning priority'),
),
]
18 changes: 18 additions & 0 deletions djangocms_blog/migrations/0042_alter_post_enable_comments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.2.9 on 2021-12-17 12:04

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('djangocms_blog', '0041_auto_20211214_1137'),
]

operations = [
migrations.AlterField(
model_name='post',
name='enable_comments',
field=models.BooleanField(default=False, verbose_name='enable comments on post'),
),
]
Loading