From b8f855cc77957de3c56397da886a813c8b2dfc65 Mon Sep 17 00:00:00 2001 From: Haricot Date: Thu, 15 Oct 2020 15:40:04 +0200 Subject: [PATCH 01/42] setup.py:add django-cms 4 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index bbe2a3bfd..53f426af4 100644 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ install_requires=[ 'django>=2.1,<3.1', 'django-classy-tags>=1.0', - 'django-cms>=3.5,<4', + 'django-cms>=3.5', 'django-entangled', 'djangocms-text-ckeditor>=3.7', 'jsonfield', From 2ca00a8e8ae6a5931b453f8681120c5698840e41 Mon Sep 17 00:00:00 2001 From: Haricot Date: Fri, 16 Oct 2020 13:42:51 +0200 Subject: [PATCH 02/42] adaptation to DjangoCMS 4 --- cmsplugin_cascade/admin.py | 11 ++----- cmsplugin_cascade/link/forms.py | 3 +- cmsplugin_cascade/utils_helpers.py | 51 ++++++++++++++++++++++++++++++ examples/bs4demo/settings.py | 3 ++ examples/pyproject.toml | 4 ++- 5 files changed, 61 insertions(+), 11 deletions(-) create mode 100644 cmsplugin_cascade/utils_helpers.py diff --git a/cmsplugin_cascade/admin.py b/cmsplugin_cascade/admin.py index 041a5a84f..4163b565a 100644 --- a/cmsplugin_cascade/admin.py +++ b/cmsplugin_cascade/admin.py @@ -4,14 +4,12 @@ from django.contrib import admin from django.contrib.sites.shortcuts import get_current_site from django.forms import Media, widgets -from django.db.models import Q from django.http import JsonResponse, HttpResponseForbidden, HttpResponseNotFound from django.urls import reverse from django.utils.translation import get_language_from_request -from cms.models.pagemodel import Page from cms.extensions import PageExtensionAdmin -from cms.utils.page import get_page_from_path +from cmsplugin_cascade.utils_helpers import get_page_from_path, get_matching_published_pages from cmsplugin_cascade.models import CascadePage, IconFont from cmsplugin_cascade.link.forms import format_page_link @@ -78,12 +76,7 @@ def get_published_pagelist(self, request, *args, **kwargs): return JsonResponse(data) # otherwise resolve by search term - matching_published_pages = Page.objects.published().public().filter( - Q(title_set__title__icontains=query_term, title_set__language=language) - | Q(title_set__path__icontains=query_term, title_set__language=language) - | Q(title_set__menu_title__icontains=query_term, title_set__language=language) - | Q(title_set__page_title__icontains=query_term, title_set__language=language) - ).distinct().order_by('title_set__title').iterator() + matching_published_pages = get_matching_published_pages() for page in matching_published_pages: data['results'].append(self.get_result_set(language, page)) diff --git a/cmsplugin_cascade/link/forms.py b/cmsplugin_cascade/link/forms.py index 04e447fed..1ed54c41f 100644 --- a/cmsplugin_cascade/link/forms.py +++ b/cmsplugin_cascade/link/forms.py @@ -12,6 +12,7 @@ from cms.utils import get_current_site from cms.models import Page +from cmsplugin_cascade.utils_helpers import get_qs_pages_public from entangled.forms import EntangledModelFormMixin, get_related_object from filer.models.filemodels import File as FilerFileModel from filer.fields.file import AdminFileWidget, FilerFileField @@ -54,7 +55,7 @@ class LinkSearchField(ModelChoiceField): widget = PageSelect2Widget() def __init__(self, *args, **kwargs): - queryset = Page.objects.public() + queryset = get_qs_pages_public() try: queryset = queryset.published().on_site(get_current_site()) except: diff --git a/cmsplugin_cascade/utils_helpers.py b/cmsplugin_cascade/utils_helpers.py new file mode 100644 index 000000000..3779dc32d --- /dev/null +++ b/cmsplugin_cascade/utils_helpers.py @@ -0,0 +1,51 @@ +from distutils.version import LooseVersion +from django.conf import settings +from cms import __version__ as CMS_VERSION +from cms.models.pagemodel import Page +from django.db.models import Q +from cms.sitemaps import CMSSitemap + +CMS_ = LooseVersion(CMS_VERSION) < LooseVersion('4.0') + +def get_page_from_path(site, path): + if CMS_: + from cms.utils.page import get_page_from_path + page = get_page_from_path(site, path) + else: + from cms.models import PageUrl + page_urls = ( + PageUrl + .objects + .get_for_site(site) + .filter(path=path) + .select_related('page__node') + ) + page_urls = list(page_urls) + page = page_urls.page + return page + +def get_matching_published_pages(query_term, language): + # otherwise resolve by search term + if CMS_: + matching_published_pages = Page.objects.published().public().filter( + Q(title_set__title__icontains=query_term, title_set__language=language) + | Q(title_set__path__icontains=query_term, title_set__language=language) + | Q(title_set__menu_title__icontains=query_term, title_set__language=language) + | Q(title_set__page_title__icontains=query_term, title_set__language=language) + ).distinct().order_by('title_set__title').iterator() + else: + matching_published_pages = Page.objects.filter( + Q(pagecontent_set__title__icontains=query_term, pagecontent_set__language=language) + | Q(urls__path__icontains=query_term, pagecontent_set__language=language) + | Q(pagecontent_set__menu_title__icontains=query_term, pagecontent_set__language=language) + | Q(pagecontent_set__page_title__icontains=query_term, pagecontent_set__language=language) + ).distinct().order_by('pagecontent_set__title').iterator() + return matching_published_pages + +def get_qs_pages_public(): + if CMS_: + queryset = Page.objects.public() + else: + name_page_public = [ str(page_url.page) for page_url in CMSSitemap().items()[:15]] + queryset = Page.objects.filter(pagecontent_set__title__in=name_page_public) + return queryset diff --git a/examples/bs4demo/settings.py b/examples/bs4demo/settings.py index 30532ead0..d5eae714f 100644 --- a/examples/bs4demo/settings.py +++ b/examples/bs4demo/settings.py @@ -53,6 +53,7 @@ 'cmsplugin_cascade.sharable', 'cmsplugin_cascade.segmentation', 'cms', + 'djangocms_alias', 'cms_bootstrap', 'adminsortable2', 'menus', @@ -281,6 +282,8 @@ # to access files such as fonts via staticfiles finders NODE_MODULES_URL = STATIC_URL + 'node_modules/' +VERSIONING_ALIAS_MODELS_ENABLED = False + try: from .private_settings import * except ImportError: diff --git a/examples/pyproject.toml b/examples/pyproject.toml index 8765fe2fa..0bfadcaeb 100644 --- a/examples/pyproject.toml +++ b/examples/pyproject.toml @@ -9,7 +9,9 @@ license = "MIT" python = "^3.8" [tool.poetry.dev-dependencies] -django = "<2.3" +django = "*" +django-cms = { git = "https://github.com/django-cms/django-cms", branch="release/4.0.x" } +djangocms-alias = { git = "https://github.com/divio/djangocms-alias", branch="master" } djangocms-cascade = "*" django-compressor = "*" django-filer = "*" From defa6d3de63a373dc566851da6226a0511d7349d Mon Sep 17 00:00:00 2001 From: Nicolas PASCAL Date: Fri, 16 Oct 2020 14:21:53 +0200 Subject: [PATCH 03/42] CMS4 testing matrix --- tox.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index f88d5e6b5..00f164dee 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] downloadcache = {toxworkdir}/_download/ -envlist = coverage-clean, py{35,36,37,38}-django{21,22,30}-cms{36,37}, coverage-report +envlist = coverage-clean, py{35,36,37,38}-django{21,22,30}-cms{36,37,40}, coverage-report [testenv] # usedevelop is needed to collect coverage data @@ -17,7 +17,7 @@ deps = coverage cms36: django-cms<3.7 cms37: django-cms<3.8 - + cms40: git+https://github.com/django-cms/django-cms@release/4.0.x#egg=django-cms setenv = PYTHONPATH = {toxinidir} From 58eb628fa1798a47992e6d3c5b2864491b850f03 Mon Sep 17 00:00:00 2001 From: Nicolas PASCAL Date: Fri, 16 Oct 2020 14:36:36 +0200 Subject: [PATCH 04/42] Update admin.py --- cmsplugin_cascade/admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmsplugin_cascade/admin.py b/cmsplugin_cascade/admin.py index f5f489113..6f4fb62ba 100644 --- a/cmsplugin_cascade/admin.py +++ b/cmsplugin_cascade/admin.py @@ -9,7 +9,7 @@ from django.utils.translation import get_language_from_request from cms.extensions import PageExtensionAdmin -from cmsplugin_cascade.utils_helpers import get_page_from_path, get_matching_published_pages +from cmsplugin_cascade.utils_helpers import get_page_from_path, get_matching_published_pages from cmsplugin_cascade.models import CascadePage, IconFont from cmsplugin_cascade.link.forms import format_page_link From 04a2a8d38682ec15d928284d05f7f54fc6e185a8 Mon Sep 17 00:00:00 2001 From: Nicolas PASCAL Date: Fri, 16 Oct 2020 14:36:57 +0200 Subject: [PATCH 05/42] Update .travis.yml --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 4ea21820e..346969140 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,7 @@ env: - DJANGOVER=django22 CMSVER=cms36 - DJANGOVER=django22 CMSVER=cms37 - DJANGOVER=django30 CMSVER=cms37 + - DJANGOVER=django30 CMSVER=cms40 matrix: allow_failures: @@ -20,6 +21,8 @@ matrix: env: DJANGOVER=django22 CMSVER=cms36 - python: 3.8 env: DJANGOVER=django30 CMSVER=cms37 + - python: 3.8 + env: DJANGOVER=django30 CMSVER=cms40 install: - pip install tox From 568e58158cc7cb295f8f3aa29fd73eb4f05524b6 Mon Sep 17 00:00:00 2001 From: Nicolas PASCAL Date: Fri, 16 Oct 2020 15:32:05 +0200 Subject: [PATCH 06/42] Update .travis.yml --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 346969140..86dff3cdb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,7 @@ env: - DJANGOVER=django22 CMSVER=cms36 - DJANGOVER=django22 CMSVER=cms37 - DJANGOVER=django30 CMSVER=cms37 + - DJANGOVER=django22 CMSVER=cms40 - DJANGOVER=django30 CMSVER=cms40 matrix: @@ -21,8 +22,6 @@ matrix: env: DJANGOVER=django22 CMSVER=cms36 - python: 3.8 env: DJANGOVER=django30 CMSVER=cms37 - - python: 3.8 - env: DJANGOVER=django30 CMSVER=cms40 install: - pip install tox From 5f6fe38a4ed6e0996824719cfd95c0fa37d61a8c Mon Sep 17 00:00:00 2001 From: Nicolas PASCAL Date: Fri, 16 Oct 2020 15:56:48 +0200 Subject: [PATCH 07/42] Empty file cmsplugin_cascade/link/settings.py --- cmsplugin_cascade/link/settings.py | 1 + 1 file changed, 1 insertion(+) create mode 100644 cmsplugin_cascade/link/settings.py diff --git a/cmsplugin_cascade/link/settings.py b/cmsplugin_cascade/link/settings.py new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/cmsplugin_cascade/link/settings.py @@ -0,0 +1 @@ + From ef8a847af594c04c8f668a287001a05d758e5034 Mon Sep 17 00:00:00 2001 From: Nicolas PASCAL Date: Sat, 17 Oct 2020 16:51:22 +0200 Subject: [PATCH 08/42] get_qs_pages_public:fix no such table: django_site --- cmsplugin_cascade/utils_helpers.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cmsplugin_cascade/utils_helpers.py b/cmsplugin_cascade/utils_helpers.py index 3779dc32d..173cbe554 100644 --- a/cmsplugin_cascade/utils_helpers.py +++ b/cmsplugin_cascade/utils_helpers.py @@ -46,6 +46,10 @@ def get_qs_pages_public(): if CMS_: queryset = Page.objects.public() else: - name_page_public = [ str(page_url.page) for page_url in CMSSitemap().items()[:15]] - queryset = Page.objects.filter(pagecontent_set__title__in=name_page_public) + try: + name_page_public = [str(page_url.page) for page_url in CMSSitemap().items()[:15]] + queryset = Page.objects.filter(pagecontent_set__title__in=name_page_public) + except: + # intial empty db + queryset = Page.objects return queryset From 8e0d328687bf1b809c2c371522fdf5f060cd30f7 Mon Sep 17 00:00:00 2001 From: Haricot Date: Sat, 17 Oct 2020 19:21:02 +0200 Subject: [PATCH 09/42] add utils_helpers:get_plugins_as_layered_tree --- cmsplugin_cascade/utils_helpers.py | 9 +++++++++ tests/bootstrap4/test_accordion.py | 5 +++-- tests/bootstrap4/test_container.py | 4 ++-- tests/test_http.py | 6 +++++- tests/test_segmentation.py | 4 ++-- 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/cmsplugin_cascade/utils_helpers.py b/cmsplugin_cascade/utils_helpers.py index 173cbe554..adfdb9f82 100644 --- a/cmsplugin_cascade/utils_helpers.py +++ b/cmsplugin_cascade/utils_helpers.py @@ -53,3 +53,12 @@ def get_qs_pages_public(): # intial empty db queryset = Page.objects return queryset + +def get_plugins_as_layered_tree(plugins): + if CMS_: + from cms.utils.plugins import build_plugin_tree + return build_plugin_tree(plugins) + else: + from cms.utils.plugins import get_plugins_as_layered_tree as _get_plugins_as_layered_tree + return _get_plugins_as_layered_tree(plugins) + diff --git a/tests/bootstrap4/test_accordion.py b/tests/bootstrap4/test_accordion.py index 9b4a124f4..82a6b636a 100644 --- a/tests/bootstrap4/test_accordion.py +++ b/tests/bootstrap4/test_accordion.py @@ -2,7 +2,8 @@ from django.template.context import RequestContext from cms.api import add_plugin from cms.plugin_rendering import ContentRenderer -from cms.utils.plugins import build_plugin_tree +from django.utils.html import strip_spaces_between_tags, strip_tags +from cmsplugin_cascade.utils_helpers import get_plugins_as_layered_tree from cmsplugin_cascade.models import CascadeElement from cmsplugin_cascade.bootstrap4.accordion import BootstrapAccordionGroupPlugin, BootstrapAccordionPlugin @@ -45,7 +46,7 @@ def test_edit_accordion_group(rf, admin_site, bootstrap_accordion): assert group_model.glossary['body_padding'] is True # render the plugin - build_plugin_tree([accordion_model, group_model]) + get_plugins_as_layered_tree([accordion_model, group_model]) context = RequestContext(request) content_renderer = ContentRenderer(request) html = content_renderer.render_plugin(accordion_model, context).strip() diff --git a/tests/bootstrap4/test_container.py b/tests/bootstrap4/test_container.py index cd4b5715d..2ce252ed6 100644 --- a/tests/bootstrap4/test_container.py +++ b/tests/bootstrap4/test_container.py @@ -2,7 +2,7 @@ from bs4 import BeautifulSoup from django.utils.html import strip_spaces_between_tags from cms.plugin_rendering import ContentRenderer -from cms.utils.plugins import build_plugin_tree +from cmsplugin_cascade.utils_helpers import get_plugins_as_layered_tree from cmsplugin_cascade.models import CascadeElement from cmsplugin_cascade.bootstrap4.container import BootstrapColumnPlugin @@ -76,7 +76,7 @@ def test_edit_bootstrap_row(rf, bootstrap_row): row_model.parent.child_plugin_instances for plugin in plugin_list: plugin.refresh_from_db() - build_plugin_tree(plugin_list) + get_plugins_as_layered_tree(plugin_list) html = content_renderer.render_plugin(container_model, context) html = strip_spaces_between_tags(html).strip() assert html == '
' \ diff --git a/tests/test_http.py b/tests/test_http.py index 8a658a66f..7730c4ae6 100644 --- a/tests/test_http.py +++ b/tests/test_http.py @@ -6,9 +6,13 @@ from django.test.utils import override_settings from cms.models import Page from cms.utils.compat.dj import is_installed -from cms.test_utils.testcases import CMSTestCase, URL_CMS_PAGE_ADD, URL_CMS_PLUGIN_ADD +from cms.test_utils.testcases import CMSTestCase, URL_CMS_PAGE +from urllib.parse import urljoin + import pytest +URL_CMS_PAGE_ADD = urljoin(URL_CMS_PAGE, "add/") +URL_CMS_PLUGIN_ADD = urljoin(URL_CMS_PAGE, "add-plugin/") APPS_WITHOUT_REVERSION = [app for app in settings.INSTALLED_APPS if app != 'reversion'] diff --git a/tests/test_segmentation.py b/tests/test_segmentation.py index 9c5083bd1..18ab7b745 100644 --- a/tests/test_segmentation.py +++ b/tests/test_segmentation.py @@ -7,7 +7,7 @@ from django.contrib.auth import get_user_model from cms.api import add_plugin -from cms.utils.plugins import build_plugin_tree +from cmsplugin_cascade.utils_helpers import get_plugins_as_layered_tree from djangocms_text_ckeditor.cms_plugins import TextPlugin from cmsplugin_cascade.generic.simple_wrapper import SimpleWrapperPlugin from cmsplugin_cascade.segmentation.cms_plugins import SegmentPlugin @@ -56,7 +56,7 @@ def test_plugin_context(self): # build the DOM plugin_list = [wrapper_model, if_segment_model, text_model_admin, elif_segment_model, text_model_staff, else_segment_model, text_model_anon] - build_plugin_tree(plugin_list) + get_plugins_as_layered_tree(plugin_list) # test for if-segment (render the plugins as admin user) self.request.user = self.admin_user From d28fd808cf104b3f72eab5b3cb94b5d6f2b3923d Mon Sep 17 00:00:00 2001 From: Haricot Date: Sat, 17 Oct 2020 20:58:21 +0200 Subject: [PATCH 10/42] change version disto for update sqlite --- .travis.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.travis.yml b/.travis.yml index 86dff3cdb..4ef545e4f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,5 @@ +sudo: required +dist: trusty language: python python: @@ -23,6 +25,14 @@ matrix: - python: 3.8 env: DJANGOVER=django30 CMSVER=cms37 +before_install: + - sudo apt-get autoremove sqlite3 + - sudo apt-get install python-software-properties + - sudo apt-add-repository -y ppa:travis-ci/sqlite3 + - sudo apt-get -y update + - sudo apt-cache show sqlite3 + - sudo apt-get install sqlite3=3.7.15.1-1~travis1 + install: - pip install tox From 9ab587330034e56945af5a1418964c505accf19c Mon Sep 17 00:00:00 2001 From: Haricot Date: Sat, 17 Oct 2020 21:04:22 +0200 Subject: [PATCH 11/42] update .travis --- .travis.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4ef545e4f..7ad4d0549 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,14 +25,6 @@ matrix: - python: 3.8 env: DJANGOVER=django30 CMSVER=cms37 -before_install: - - sudo apt-get autoremove sqlite3 - - sudo apt-get install python-software-properties - - sudo apt-add-repository -y ppa:travis-ci/sqlite3 - - sudo apt-get -y update - - sudo apt-cache show sqlite3 - - sudo apt-get install sqlite3=3.7.15.1-1~travis1 - install: - pip install tox From 29aa89076825d0c959fc6a148f81d07cee3ec82d Mon Sep 17 00:00:00 2001 From: Haricot Date: Sat, 17 Oct 2020 21:15:15 +0200 Subject: [PATCH 12/42] update .travis --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7ad4d0549..b7f00d10b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,4 @@ -sudo: required -dist: trusty +dist: focal language: python python: From a9b53c3ba1fbd40c8c10f4393c2fbf8afb10af7e Mon Sep 17 00:00:00 2001 From: Haricot Date: Sun, 18 Oct 2020 10:46:29 +0200 Subject: [PATCH 13/42] use get_placeholders if CMS4 --- tests/conftest.py | 7 +++++-- tests/test_base.py | 9 +++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index c7030cc92..25c0c932c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,7 +6,7 @@ from django.contrib.auth.hashers import make_password from cms.api import create_page from cmsplugin_cascade.models import CascadePage - +from cmsplugin_cascade.utils_helpers import CMS_ @pytest.fixture def admin_site(): @@ -26,7 +26,10 @@ def cms_page(): @pytest.fixture @pytest.mark.django_db def cms_placeholder(cms_page): - placeholder = cms_page.placeholders.get(slot='Main Content') + if CMS_: + placeholder = cms_page.placeholders.get(slot='Main Content') + else: + placeholder = cms_page.get_placeholders(cms_page.language).get(slot='Main Content') return placeholder diff --git a/tests/test_base.py b/tests/test_base.py index 0cdc6ad31..4260da52f 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -9,7 +9,7 @@ from cms.api import create_page from cms.test_utils.testcases import CMSTestCase from cmsplugin_cascade.models import CascadePage - +from cmsplugin_cascade.utils_helpers import CMS_ class CascadeTestCase(CMSTestCase): home_page = None @@ -20,9 +20,10 @@ def setUp(self): # >= Django CMS v3.5.x self.home_page.set_as_homepage() CascadePage.assure_relation(self.home_page) - - self.placeholder = self.home_page.placeholders.get(slot='Main Content') - + if CMS_: + self.placeholder = self.home_page.placeholders.get(slot='Main Content') + else: + self.placeholder = self.home_page.get_placeholders(self.home_page.language).get(slot='Main Content') self.request = self.get_request(self.home_page, 'en') self.admin_site = admin.sites.AdminSite() From c685b2a6493bda30baa650c05139b942712832ab Mon Sep 17 00:00:00 2001 From: Haricot Date: Sun, 18 Oct 2020 11:16:59 +0200 Subject: [PATCH 14/42] fix test use cms_page.languages --- tests/conftest.py | 2 +- tests/test_base.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 25c0c932c..3e087caa3 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -29,7 +29,7 @@ def cms_placeholder(cms_page): if CMS_: placeholder = cms_page.placeholders.get(slot='Main Content') else: - placeholder = cms_page.get_placeholders(cms_page.language).get(slot='Main Content') + placeholder = cms_page.get_placeholders(cms_page.languages).get(slot='Main Content')s return placeholder diff --git a/tests/test_base.py b/tests/test_base.py index 4260da52f..55f6135ee 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -23,7 +23,7 @@ def setUp(self): if CMS_: self.placeholder = self.home_page.placeholders.get(slot='Main Content') else: - self.placeholder = self.home_page.get_placeholders(self.home_page.language).get(slot='Main Content') + self.placeholder = self.home_page.get_placeholders(self.home_page.languages).get(slot='Main Content') self.request = self.get_request(self.home_page, 'en') self.admin_site = admin.sites.AdminSite() From 5a04d7d54d0c9d9f7995f94aa75719a741f85263 Mon Sep 17 00:00:00 2001 From: Haricot Date: Sun, 18 Oct 2020 11:24:06 +0200 Subject: [PATCH 15/42] fix syntax --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 3e087caa3..f50315864 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -29,7 +29,7 @@ def cms_placeholder(cms_page): if CMS_: placeholder = cms_page.placeholders.get(slot='Main Content') else: - placeholder = cms_page.get_placeholders(cms_page.languages).get(slot='Main Content')s + placeholder = cms_page.get_placeholders(cms_page.languages).get(slot='Main Content') return placeholder From 6fc62988df018dd5c8fd66b85c0114f9974b0ed9 Mon Sep 17 00:00:00 2001 From: Haricot Date: Mon, 19 Oct 2020 16:53:56 +0200 Subject: [PATCH 16/42] fix cascade:CMSPlugin without MP_Node --- cmsplugin_cascade/admin.py | 2 +- cmsplugin_cascade/bootstrap4/container.py | 13 ++--------- cmsplugin_cascade/models_base.py | 13 ++++++++--- cmsplugin_cascade/plugin_base.py | 10 ++++---- cmsplugin_cascade/utils_helpers.py | 28 ++++++++++++++++++++++- 5 files changed, 45 insertions(+), 21 deletions(-) diff --git a/cmsplugin_cascade/admin.py b/cmsplugin_cascade/admin.py index 6f4fb62ba..96894526c 100644 --- a/cmsplugin_cascade/admin.py +++ b/cmsplugin_cascade/admin.py @@ -77,7 +77,7 @@ def get_published_pagelist(self, request, *args, **kwargs): return JsonResponse(data) # otherwise resolve by search term - matching_published_pages = get_matching_published_pages() + matching_published_pages = get_matching_published_pages(query_term,language) for page in matching_published_pages: data['results'].append(self.get_result_set(language, page)) diff --git a/cmsplugin_cascade/bootstrap4/container.py b/cmsplugin_cascade/bootstrap4/container.py index 3b829a51a..d44580091 100644 --- a/cmsplugin_cascade/bootstrap4/container.py +++ b/cmsplugin_cascade/bootstrap4/container.py @@ -10,10 +10,10 @@ from cmsplugin_cascade import app_settings from cmsplugin_cascade.bootstrap4.grid import Breakpoint from cmsplugin_cascade.forms import ManageChildrenFormMixin +from cmsplugin_cascade.utils_helpers import CMS_, get_ancestor_container from .plugin_base import BootstrapPluginBase from . import grid - def get_widget_choices(): breakpoints = app_settings.CMSPLUGIN_CASCADE['bootstrap4']['fluid_bounds'] widget_choices = [] @@ -195,16 +195,7 @@ def choose_help_text(*phrases): return phrases[1].format(bs4_breakpoints[first].min) else: return phrases[2] - - if 'parent' in self._cms_initial_attributes: - container=self._cms_initial_attributes['parent'].get_ancestors().order_by('depth').last().get_bound_plugin() - else: - containers=obj.get_ancestors().filter(plugin_type='BootstrapContainerPlugin') - if containers: - container=containers.order_by('depth').last().get_bound_plugin() - else: - jumbotrons=obj.get_ancestors().filter(plugin_type='BootstrapJumbotronPlugin') - container=jumbotrons.order_by('depth').last().get_bound_plugin() + container = get_ancestor_container(obj).get_bound_plugin() breakpoints = container.glossary['breakpoints'] width_fields, offset_fields, reorder_fields, responsive_fields = {}, {}, {}, {} diff --git a/cmsplugin_cascade/models_base.py b/cmsplugin_cascade/models_base.py index 4a28650a8..01fb7a10e 100644 --- a/cmsplugin_cascade/models_base.py +++ b/cmsplugin_cascade/models_base.py @@ -6,7 +6,7 @@ from cms.models import CMSPlugin from cms.plugin_pool import plugin_pool from cms.utils.placeholder import get_placeholder_conf - +from cmsplugin_cascade.utils_helpers import CMS_ class CascadeModelBase(CMSPlugin): """ @@ -60,9 +60,15 @@ def get_parent_instance(self): except model.DoesNotExist: continue # in case our plugin is the child of a TextPlugin, return its grandparent - parent = self.get_parent() + if CMS_: + parent = self.get_parent() + else: + parent = self.parent if parent and parent.plugin_type == 'TextPlugin': - grandparent_id = self.get_parent().parent_id + if CMS_: + grandparent_id = self.get_parent().parent_id + else: + grandparent_id = self.parent.parent_id for model in CascadeModelBase._get_cascade_elements(): try: return model.objects.get(id=grandparent_id) @@ -143,3 +149,4 @@ def _get_cascade_elements(cls): if issubclass(p.model, cls)]) cls._cached_cascade_elements = cce return cls._cached_cascade_elements + diff --git a/cmsplugin_cascade/plugin_base.py b/cmsplugin_cascade/plugin_base.py index 0150758bd..30047e040 100644 --- a/cmsplugin_cascade/plugin_base.py +++ b/cmsplugin_cascade/plugin_base.py @@ -8,6 +8,7 @@ from cms.plugin_base import CMSPluginBaseMetaclass, CMSPluginBase from cms.utils.compat.dj import is_installed from cmsplugin_cascade import app_settings +from cmsplugin_cascade.utils_helpers import get_prev_sibling from .mixins import CascadePluginMixin from .models_base import CascadeModelBase from .models import CascadeElement, SharableCascadeElement @@ -363,11 +364,9 @@ def get_previous_instance(self, obj): Return the previous plugin instance for the given object. This differs from `obj.get_prev_sibling()` which returns an unsorted sibling. """ - ordered_siblings = obj.get_siblings().filter(placeholder=obj.placeholder).order_by('position') - pos = list(ordered_siblings).index(obj.cmsplugin_ptr) - if pos > 0: - prev_sibling = ordered_siblings[pos - 1] - return prev_sibling.get_bound_plugin() + prev_sibling = get_prev_sibling(obj) + if prev_sibling: + return prev_sibling.get_bound_plugin() def get_next_instance(self, obj): """ @@ -405,3 +404,4 @@ def in_edit_mode(self, request, placeholder): if edit_mode: edit_mode = placeholder.has_change_permission(request.user) return edit_mode + diff --git a/cmsplugin_cascade/utils_helpers.py b/cmsplugin_cascade/utils_helpers.py index adfdb9f82..7df39c3ad 100644 --- a/cmsplugin_cascade/utils_helpers.py +++ b/cmsplugin_cascade/utils_helpers.py @@ -50,7 +50,7 @@ def get_qs_pages_public(): name_page_public = [str(page_url.page) for page_url in CMSSitemap().items()[:15]] queryset = Page.objects.filter(pagecontent_set__title__in=name_page_public) except: - # intial empty db + #intial empty db queryset = Page.objects return queryset @@ -62,3 +62,29 @@ def get_plugins_as_layered_tree(plugins): from cms.utils.plugins import get_plugins_as_layered_tree as _get_plugins_as_layered_tree return _get_plugins_as_layered_tree(plugins) +def get_ancestor_container(plugin): + if plugin.parent: + while plugin : + if str(plugin.plugin_type) in ['BootstrapContainerPlugin', 'BootstrapJumbotronPlugin']: + return plugin + elif plugin.parent: + plugin = plugin.parent + else: + return plugin + +def get_prev_sibling(plugin): + if CMS_: + ordered_siblings = plugin.get_siblings().filter(placeholder=plugin.placeholder).order_by('position') + pos = list(ordered_siblings).index(plugin.cmsplugin_ptr) + if pos > 0: + prev_sibling = ordered_siblings[pos - 1] + return prev_sibling.get_bound_plugin() + else: + if plugin.parent: + prev_sibling = plugin.parent.get_children().order_by('position').filter(id__lt=plugin.id).last() + if prev_sibling: + return prev_sibling.get_bound_plugin() + else: + prev_sibling = plugin.placeholder.get_plugin_tree_order(language=obj.language).filter(id__lt=plugin.id).last() + if prev_sibling: + return prev_sibling.get_bound_plugin() From 0618c65f8b1dda6fc6f6e9d18fbac7963983fe96 Mon Sep 17 00:00:00 2001 From: Haricot Date: Tue, 20 Oct 2020 08:56:29 +0200 Subject: [PATCH 17/42] update test_container, test_accordion --- tests/bootstrap4/test_accordion.py | 2 +- tests/bootstrap4/test_container.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/bootstrap4/test_accordion.py b/tests/bootstrap4/test_accordion.py index 82a6b636a..c42d63588 100644 --- a/tests/bootstrap4/test_accordion.py +++ b/tests/bootstrap4/test_accordion.py @@ -35,7 +35,7 @@ def bootstrap_accordion(rf, admin_site, bootstrap_column): def test_edit_accordion_group(rf, admin_site, bootstrap_accordion): request = rf.get('/') accordion_plugin, accordion_model = bootstrap_accordion - first_group = accordion_model.get_first_child() + first_group = accordion_model.get_children().first() group_model, group_plugin = first_group.get_plugin_instance(admin_site) data = {'heading': "Hello", 'body_padding': 'on'} ModelForm = group_plugin.get_form(request, group_model) diff --git a/tests/bootstrap4/test_container.py b/tests/bootstrap4/test_container.py index 2ce252ed6..f389e4fda 100644 --- a/tests/bootstrap4/test_container.py +++ b/tests/bootstrap4/test_container.py @@ -27,7 +27,6 @@ def test_edit_bootstrap_container(rf, bootstrap_container): assert 'fluid' in container_model.glossary assert str(container_model) == "for Landscape Phones, Tablets" - @pytest.mark.django_db def test_edit_bootstrap_row(rf, bootstrap_row): row_plugin, row_model = bootstrap_row @@ -42,7 +41,7 @@ def test_edit_bootstrap_row(rf, bootstrap_row): plugin_list = [container_model, row_model] # we now should have three columns attached to the row - assert row_model.get_descendant_count() == 3 + assert len(list(row_model.get_descendants())) == 3 for cms_plugin in row_model.get_descendants(): column_model, column_plugin = cms_plugin.get_plugin_instance() assert isinstance(column_model, CascadeElement) From 37bdd3199e89f63d5a65b513b9fb255b04969d10 Mon Sep 17 00:00:00 2001 From: Haricot Date: Tue, 20 Oct 2020 11:43:11 +0200 Subject: [PATCH 18/42] wip update --- cmsplugin_cascade/bootstrap4/container.py | 17 ++++++++++------- cmsplugin_cascade/utils_helpers.py | 9 +++++++-- examples/bs4demo/settings.py | 2 +- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/cmsplugin_cascade/bootstrap4/container.py b/cmsplugin_cascade/bootstrap4/container.py index d44580091..520cb2e03 100644 --- a/cmsplugin_cascade/bootstrap4/container.py +++ b/cmsplugin_cascade/bootstrap4/container.py @@ -10,7 +10,7 @@ from cmsplugin_cascade import app_settings from cmsplugin_cascade.bootstrap4.grid import Breakpoint from cmsplugin_cascade.forms import ManageChildrenFormMixin -from cmsplugin_cascade.utils_helpers import CMS_, get_ancestor_container +from cmsplugin_cascade.utils_helpers import get_ancestor from .plugin_base import BootstrapPluginBase from . import grid @@ -127,9 +127,11 @@ class Meta: class RowGridMixin(object): def get_grid_instance(self): row = grid.Bootstrap4Row() - query = Q(plugin_type='BootstrapContainerPlugin') | Q(plugin_type='BootstrapColumnPlugin') \ - | Q(plugin_type='BootstrapJumbotronPlugin') - container = self.get_ancestors().order_by('depth').filter(query).last().get_bound_plugin().get_grid_instance() + #query = Q(plugin_type='BootstrapContainerPlugin') | Q(plugin_type='BootstrapColumnPlugin') \ + # | Q(plugin_type='BootstrapJumbotronPlugin') + ancestor_parent_name = ['BootstrapContainerPlugin', 'BootstrapColumnPlugin', 'BootstrapJumbotronPlugin'] + container = get_ancestor(None, self, ancestor_parent_name).get_bound_plugin().get_grid_instance() + #container = self.get_ancestors().order_by('depth').filter(query).last().get_bound_plugin().get_grid_instance() container.add_row(row) return row @@ -162,10 +164,11 @@ class ColumnGridMixin(object): def get_grid_instance(self): column = None query = Q(plugin_type='BootstrapRowPlugin') - row_obj = self.get_ancestors().order_by('depth').filter(query).last().get_bound_plugin() + row_obj = get_ancestor(None, self,['BootstrapRowPlugin']).get_bound_plugin() # column_siblings = row_obj.get_descendants().order_by('depth').filter(plugin_type='BootstrapColumnPlugin') row = row_obj.get_grid_instance() - for column_sibling in self.get_siblings(): + siblings = self.parent.get_children() + for column_sibling in siblings: classes = [val for key, val in column_sibling.get_bound_plugin().glossary.items() if key in self.valid_keys and val] if column_sibling.pk == self.pk: @@ -195,7 +198,7 @@ def choose_help_text(*phrases): return phrases[1].format(bs4_breakpoints[first].min) else: return phrases[2] - container = get_ancestor_container(obj).get_bound_plugin() + container = get_ancestor(self, obj, ['BootstrapContainerPlugin', 'BootstrapJumbotronPlugin']).get_bound_plugin() breakpoints = container.glossary['breakpoints'] width_fields, offset_fields, reorder_fields, responsive_fields = {}, {}, {}, {} diff --git a/cmsplugin_cascade/utils_helpers.py b/cmsplugin_cascade/utils_helpers.py index 7df39c3ad..2e456e777 100644 --- a/cmsplugin_cascade/utils_helpers.py +++ b/cmsplugin_cascade/utils_helpers.py @@ -62,10 +62,15 @@ def get_plugins_as_layered_tree(plugins): from cms.utils.plugins import get_plugins_as_layered_tree as _get_plugins_as_layered_tree return _get_plugins_as_layered_tree(plugins) -def get_ancestor_container(plugin): +def get_ancestor(cls, plugin, list_plugins_name): + if hasattr(cls, '_cms_initial_attributes') and 'parent' in cls._cms_initial_attributes \ + and cls._cms_initial_attributes['parent']: + plugin = cls + plugin.plugin_type = cls._cms_initial_attributes['plugin_type'] + plugin.parent = cls._cms_initial_attributes['parent'] if plugin.parent: while plugin : - if str(plugin.plugin_type) in ['BootstrapContainerPlugin', 'BootstrapJumbotronPlugin']: + if str(plugin.plugin_type) in list_plugins_name: return plugin elif plugin.parent: plugin = plugin.parent diff --git a/examples/bs4demo/settings.py b/examples/bs4demo/settings.py index d5eae714f..2cd260dd8 100644 --- a/examples/bs4demo/settings.py +++ b/examples/bs4demo/settings.py @@ -218,7 +218,7 @@ 'plugins_with_sharables': { 'BootstrapImagePlugin': ('image_shapes', 'image_width_responsive', 'image_width_fixed', 'image_height', 'resize_options',), - 'BootstrapPicturePlugin': ('image_shapes', 'responsive_heights', 'image_size', 'resize_options',), + 'BootstrapPicturePlugin': ('image_shapes', 'responsive_heights', 'resize_options',), }, 'exclude_hiding_plugin': ('SegmentPlugin', 'Badge'), 'allow_plugin_hiding': True, From 64c1f26670548486fb4d26910683c0bdd66f37c7 Mon Sep 17 00:00:00 2001 From: Haricot Date: Sat, 24 Oct 2020 16:14:59 +0200 Subject: [PATCH 19/42] refactor get_ancestor plugin --- cmsplugin_cascade/utils_helpers.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/cmsplugin_cascade/utils_helpers.py b/cmsplugin_cascade/utils_helpers.py index 2e456e777..008d2bac0 100644 --- a/cmsplugin_cascade/utils_helpers.py +++ b/cmsplugin_cascade/utils_helpers.py @@ -66,16 +66,17 @@ def get_ancestor(cls, plugin, list_plugins_name): if hasattr(cls, '_cms_initial_attributes') and 'parent' in cls._cms_initial_attributes \ and cls._cms_initial_attributes['parent']: plugin = cls - plugin.plugin_type = cls._cms_initial_attributes['plugin_type'] + plugin.plugin_type = ['plugin_type'] plugin.parent = cls._cms_initial_attributes['parent'] - if plugin.parent: - while plugin : - if str(plugin.plugin_type) in list_plugins_name: - return plugin - elif plugin.parent: - plugin = plugin.parent - else: - return plugin + plugin.postion = cls._cms_initial_attributes['position'] + plugin.placeholder = cls._cms_initial_attributes['placeholder'] + plugin.language = cls._cms_initial_attributes['language'] + + ancestor_plugin = plugin.placeholder.get_plugins().filter( + plugin_type__in=list_plugins_name, + position__range=[0, plugin.position]).order_by('position')[0] + return ancestor_plugin + def get_prev_sibling(plugin): if CMS_: From 2e90289026888f39d976e4eaf5e0ba74de162d4a Mon Sep 17 00:00:00 2001 From: Haricot Date: Sat, 24 Oct 2020 16:43:08 +0200 Subject: [PATCH 20/42] update utils_helpers.py --- cmsplugin_cascade/utils_helpers.py | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/cmsplugin_cascade/utils_helpers.py b/cmsplugin_cascade/utils_helpers.py index 008d2bac0..d5a1a50b0 100644 --- a/cmsplugin_cascade/utils_helpers.py +++ b/cmsplugin_cascade/utils_helpers.py @@ -9,8 +9,8 @@ def get_page_from_path(site, path): if CMS_: - from cms.utils.page import get_page_from_path - page = get_page_from_path(site, path) + from cms.utils.page import get_page_from_path as get_page_from_path_CMS_ + page = get_page_from_path_CMS_(site, path) else: from cms.models import PageUrl page_urls = ( @@ -65,32 +65,28 @@ def get_plugins_as_layered_tree(plugins): def get_ancestor(cls, plugin, list_plugins_name): if hasattr(cls, '_cms_initial_attributes') and 'parent' in cls._cms_initial_attributes \ and cls._cms_initial_attributes['parent']: - plugin = cls - plugin.plugin_type = ['plugin_type'] - plugin.parent = cls._cms_initial_attributes['parent'] - plugin.postion = cls._cms_initial_attributes['position'] - plugin.placeholder = cls._cms_initial_attributes['placeholder'] - plugin.language = cls._cms_initial_attributes['language'] - - ancestor_plugin = plugin.placeholder.get_plugins().filter( + ancestor_plugin = self._cms_initial_attributes['placeholder'].get_plugins().filter( + plugin_type__in=list_plugins_name, + position__range=[0, cls._cms_initial_attributes['position']]).order_by('position')[0] + else: + ancestor_plugin = plugin.placeholder.get_plugins().filter( plugin_type__in=list_plugins_name, position__range=[0, plugin.position]).order_by('position')[0] return ancestor_plugin def get_prev_sibling(plugin): + prev_sibling = None if CMS_: ordered_siblings = plugin.get_siblings().filter(placeholder=plugin.placeholder).order_by('position') pos = list(ordered_siblings).index(plugin.cmsplugin_ptr) if pos > 0: prev_sibling = ordered_siblings[pos - 1] - return prev_sibling.get_bound_plugin() else: if plugin.parent: prev_sibling = plugin.parent.get_children().order_by('position').filter(id__lt=plugin.id).last() - if prev_sibling: - return prev_sibling.get_bound_plugin() else: - prev_sibling = plugin.placeholder.get_plugin_tree_order(language=obj.language).filter(id__lt=plugin.id).last() - if prev_sibling: - return prev_sibling.get_bound_plugin() + prev_sibling = plugin.placeholder.get_plugin_tree_order(language=plugin.language).filter(id__lt=plugin.id).last() + if prev_sibling: + prev_sibling = prev_sibling.get_bound_plugin() + return prev_sibling From b854318b1fcc9e6283791c104f398e74ad7651b6 Mon Sep 17 00:00:00 2001 From: Haricot Date: Sat, 24 Oct 2020 17:09:02 +0200 Subject: [PATCH 21/42] update utils_helpers.py, test_accordion.py --- cmsplugin_cascade/utils_helpers.py | 4 ++-- tests/bootstrap4/test_accordion.py | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/cmsplugin_cascade/utils_helpers.py b/cmsplugin_cascade/utils_helpers.py index d5a1a50b0..4e015b9b5 100644 --- a/cmsplugin_cascade/utils_helpers.py +++ b/cmsplugin_cascade/utils_helpers.py @@ -1,8 +1,8 @@ from distutils.version import LooseVersion from django.conf import settings +from django.db.models import Q from cms import __version__ as CMS_VERSION from cms.models.pagemodel import Page -from django.db.models import Q from cms.sitemaps import CMSSitemap CMS_ = LooseVersion(CMS_VERSION) < LooseVersion('4.0') @@ -65,7 +65,7 @@ def get_plugins_as_layered_tree(plugins): def get_ancestor(cls, plugin, list_plugins_name): if hasattr(cls, '_cms_initial_attributes') and 'parent' in cls._cms_initial_attributes \ and cls._cms_initial_attributes['parent']: - ancestor_plugin = self._cms_initial_attributes['placeholder'].get_plugins().filter( + ancestor_plugin = cls._cms_initial_attributes['placeholder'].get_plugins().filter( plugin_type__in=list_plugins_name, position__range=[0, cls._cms_initial_attributes['position']]).order_by('position')[0] else: diff --git a/tests/bootstrap4/test_accordion.py b/tests/bootstrap4/test_accordion.py index c42d63588..a883afc38 100644 --- a/tests/bootstrap4/test_accordion.py +++ b/tests/bootstrap4/test_accordion.py @@ -2,7 +2,6 @@ from django.template.context import RequestContext from cms.api import add_plugin from cms.plugin_rendering import ContentRenderer -from django.utils.html import strip_spaces_between_tags, strip_tags from cmsplugin_cascade.utils_helpers import get_plugins_as_layered_tree from cmsplugin_cascade.models import CascadeElement from cmsplugin_cascade.bootstrap4.accordion import BootstrapAccordionGroupPlugin, BootstrapAccordionPlugin From c689b63ab315eecea11fe528191986238c2c3fbc Mon Sep 17 00:00:00 2001 From: Haricot Date: Sat, 24 Oct 2020 17:14:01 +0200 Subject: [PATCH 22/42] temporary change: reduce matrix test --- .travis.yml | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index b7f00d10b..a743aedc3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,27 +2,27 @@ dist: focal language: python python: - - 3.5 - - 3.6 - - 3.7 +# - 3.5 +# - 3.6 +# - 3.7 - 3.8 env: - - DJANGOVER=django21 CMSVER=cms36 - - DJANGOVER=django22 CMSVER=cms36 + # - DJANGOVER=django21 CMSVER=cms36 + # - DJANGOVER=django22 CMSVER=cms36 - DJANGOVER=django22 CMSVER=cms37 - - DJANGOVER=django30 CMSVER=cms37 +# - DJANGOVER=django30 CMSVER=cms37 - DJANGOVER=django22 CMSVER=cms40 - - DJANGOVER=django30 CMSVER=cms40 +# - DJANGOVER=django30 CMSVER=cms40 -matrix: - allow_failures: - - python: 3.8 - env: DJANGOVER=django21 CMSVER=cms36 - - python: 3.8 - env: DJANGOVER=django22 CMSVER=cms36 - - python: 3.8 - env: DJANGOVER=django30 CMSVER=cms37 +#matrix: +# allow_failures: +# - python: 3.8 +# env: DJANGOVER=django21 CMSVER=cms36 +# - python: 3.8 +# env: DJANGOVER=django22 CMSVER=cms36 +# - python: 3.8 +# env: DJANGOVER=django30 CMSVER=cms37 install: - pip install tox From d616066f44df77cae3f0aec02c38941cd25ca188 Mon Sep 17 00:00:00 2001 From: Haricot Date: Sat, 24 Oct 2020 17:20:44 +0200 Subject: [PATCH 23/42] test_http:fix import order --- tests/test_http.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_http.py b/tests/test_http.py index 7730c4ae6..4a832a2a9 100644 --- a/tests/test_http.py +++ b/tests/test_http.py @@ -1,13 +1,13 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals import json +from urllib.parse import urljoin from django.conf import settings from django.contrib import admin from django.test.utils import override_settings from cms.models import Page from cms.utils.compat.dj import is_installed from cms.test_utils.testcases import CMSTestCase, URL_CMS_PAGE -from urllib.parse import urljoin import pytest From b18eecab2965426c3ff863e826e7ca56008e1bfa Mon Sep 17 00:00:00 2001 From: Haricot Date: Sat, 24 Oct 2020 20:27:38 +0200 Subject: [PATCH 24/42] wip sanitize_related_siblings --- cmsplugin_cascade/models_base.py | 17 +++++++++++++++-- cmsplugin_cascade/plugin_base.py | 7 ++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/cmsplugin_cascade/models_base.py b/cmsplugin_cascade/models_base.py index 01fb7a10e..1dfb65a78 100644 --- a/cmsplugin_cascade/models_base.py +++ b/cmsplugin_cascade/models_base.py @@ -1,4 +1,5 @@ from django.db import models +from django.utils import timezone from django.utils.html import mark_safe, format_html_join from django.utils.functional import cached_property import json @@ -104,6 +105,14 @@ def get_num_children(self): """ return self.get_children().count() + def sanitize_related_siblings(self): + """ + Save relateds siblings depend save_model change inherited CMSPluginBase. + """ + if self.parent: + plugins = self.__class__.objects.filter(id__in=self.parent._get_descendants_ids()) + [plugin.save() for plugin in plugins] + def sanitize_children(self): """ Recursively walk down the plugin tree and invoke method ``save(sanitize_only=True)`` for @@ -115,7 +124,7 @@ def sanitize_children(self): for child in children: child.save(sanitize_only=True) child.sanitize_children() - + @classmethod def from_db(cls, db, field_names, values): instance = cls(*values) @@ -132,10 +141,14 @@ def save(self, sanitize_only=False, *args, **kwargs): sanitized = self.plugin_class.sanitize_model(self) if sanitize_only: if sanitized: - super().save(no_signals=True) + super().save() else: super().save(*args, **kwargs) + def delete(self, *args, **kwargs): + super().delete( *args, **kwargs) + sanitized = self.plugin_class.sanitize_related_siblings_model(self) + @classmethod def _get_cascade_elements(cls): """ diff --git a/cmsplugin_cascade/plugin_base.py b/cmsplugin_cascade/plugin_base.py index 30047e040..5f55f7ff0 100644 --- a/cmsplugin_cascade/plugin_base.py +++ b/cmsplugin_cascade/plugin_base.py @@ -273,7 +273,7 @@ def get_identifier(cls, instance): return SafeText() @classmethod - def sanitize_model(cls, instance): + def sanitize_model(cls, instance,sanitize_related_sibling=[]): """ This method is called, before the model is written to the database. It can be overloaded to sanitize the current models, in case a parent model changed in a way, which might @@ -285,6 +285,11 @@ def sanitize_model(cls, instance): instance.glossary = {} return False + @classmethod + def sanitize_related_siblings_model(cls, instance): + return False + + @classmethod def get_data_representation(cls, instance): """ From 6dcc04f018154a08c871d64117956041fa884e7f Mon Sep 17 00:00:00 2001 From: Haricot Date: Sat, 24 Oct 2020 20:37:06 +0200 Subject: [PATCH 25/42] Update utils_helpers.py --- cmsplugin_cascade/utils_helpers.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/cmsplugin_cascade/utils_helpers.py b/cmsplugin_cascade/utils_helpers.py index 4e015b9b5..bcbbade01 100644 --- a/cmsplugin_cascade/utils_helpers.py +++ b/cmsplugin_cascade/utils_helpers.py @@ -7,6 +7,7 @@ CMS_ = LooseVersion(CMS_VERSION) < LooseVersion('4.0') + def get_page_from_path(site, path): if CMS_: from cms.utils.page import get_page_from_path as get_page_from_path_CMS_ @@ -24,6 +25,7 @@ def get_page_from_path(site, path): page = page_urls.page return page + def get_matching_published_pages(query_term, language): # otherwise resolve by search term if CMS_: @@ -42,6 +44,7 @@ def get_matching_published_pages(query_term, language): ).distinct().order_by('pagecontent_set__title').iterator() return matching_published_pages + def get_qs_pages_public(): if CMS_: queryset = Page.objects.public() @@ -49,11 +52,12 @@ def get_qs_pages_public(): try: name_page_public = [str(page_url.page) for page_url in CMSSitemap().items()[:15]] queryset = Page.objects.filter(pagecontent_set__title__in=name_page_public) - except: + except Page.DoesNotExist: #intial empty db queryset = Page.objects return queryset + def get_plugins_as_layered_tree(plugins): if CMS_: from cms.utils.plugins import build_plugin_tree @@ -62,12 +66,12 @@ def get_plugins_as_layered_tree(plugins): from cms.utils.plugins import get_plugins_as_layered_tree as _get_plugins_as_layered_tree return _get_plugins_as_layered_tree(plugins) -def get_ancestor(cls, plugin, list_plugins_name): - if hasattr(cls, '_cms_initial_attributes') and 'parent' in cls._cms_initial_attributes \ - and cls._cms_initial_attributes['parent']: - ancestor_plugin = cls._cms_initial_attributes['placeholder'].get_plugins().filter( + +def get_ancestor(list_plugins_name, plugin=False, _cms_initial_attributes=False): + if _cms_initial_attributes and 'parent' in _cms_initial_attributes and _cms_initial_attributes['parent']: + ancestor_plugin = _cms_initial_attributes['placeholder'].get_plugins().filter( plugin_type__in=list_plugins_name, - position__range=[0, cls._cms_initial_attributes['position']]).order_by('position')[0] + position__range=[0,_cms_initial_attributes['position']]).order_by('position')[0] else: ancestor_plugin = plugin.placeholder.get_plugins().filter( plugin_type__in=list_plugins_name, From b8c01018a5285c99ef82765d67716f7349a63a0e Mon Sep 17 00:00:00 2001 From: Haricot Date: Sat, 24 Oct 2020 20:43:07 +0200 Subject: [PATCH 26/42] Update bootstrap4/container.py --- cmsplugin_cascade/bootstrap4/container.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/cmsplugin_cascade/bootstrap4/container.py b/cmsplugin_cascade/bootstrap4/container.py index 520cb2e03..79d56fe89 100644 --- a/cmsplugin_cascade/bootstrap4/container.py +++ b/cmsplugin_cascade/bootstrap4/container.py @@ -104,6 +104,8 @@ def get_css_classes(cls, obj): def save_model(self, request, obj, form, change): super().save_model(request, obj, form, change) obj.sanitize_children() + obj.sanitize_related_siblings() + plugin_pool.register_plugin(BootstrapContainerPlugin) @@ -127,11 +129,8 @@ class Meta: class RowGridMixin(object): def get_grid_instance(self): row = grid.Bootstrap4Row() - #query = Q(plugin_type='BootstrapContainerPlugin') | Q(plugin_type='BootstrapColumnPlugin') \ - # | Q(plugin_type='BootstrapJumbotronPlugin') - ancestor_parent_name = ['BootstrapContainerPlugin', 'BootstrapColumnPlugin', 'BootstrapJumbotronPlugin'] - container = get_ancestor(None, self, ancestor_parent_name).get_bound_plugin().get_grid_instance() - #container = self.get_ancestors().order_by('depth').filter(query).last().get_bound_plugin().get_grid_instance() + class_ancestor_name = ['BootstrapContainerPlugin', 'BootstrapColumnPlugin', 'BootstrapJumbotronPlugin'] + container = get_ancestor( class_ancestor_name , plugin=self).get_bound_plugin().get_grid_instance() container.add_row(row) return row @@ -163,8 +162,7 @@ class ColumnGridMixin(object): 'xs-column-offset', 'sm-column-offset', 'md-column-offset', 'lg-column-offset', 'xs-column-offset'] def get_grid_instance(self): column = None - query = Q(plugin_type='BootstrapRowPlugin') - row_obj = get_ancestor(None, self,['BootstrapRowPlugin']).get_bound_plugin() + row_obj = get_ancestor(['BootstrapRowPlugin'], plugin=self).get_bound_plugin() # column_siblings = row_obj.get_descendants().order_by('depth').filter(plugin_type='BootstrapColumnPlugin') row = row_obj.get_grid_instance() siblings = self.parent.get_children() @@ -198,7 +196,11 @@ def choose_help_text(*phrases): return phrases[1].format(bs4_breakpoints[first].min) else: return phrases[2] - container = get_ancestor(self, obj, ['BootstrapContainerPlugin', 'BootstrapJumbotronPlugin']).get_bound_plugin() + + container = get_ancestor(['BootstrapContainerPlugin'], + _cms_initial_attributes=self._cms_initial_attributes, + plugin=obj + ).get_bound_plugin() breakpoints = container.glossary['breakpoints'] width_fields, offset_fields, reorder_fields, responsive_fields = {}, {}, {}, {} @@ -329,8 +331,11 @@ def save_model(self, request, obj, form, change): super().save_model(request, obj, form, change) obj.sanitize_children() + def sanitize_related_siblings_model(self): + self.sanitize_related_siblings() + @classmethod - def sanitize_model(cls, obj): + def sanitize_model(cls,obj): sanitized = super().sanitize_model(obj) return sanitized From 3772058bc634ec8a9932d64b30ded084a079e8d1 Mon Sep 17 00:00:00 2001 From: Haricot Date: Sat, 24 Oct 2020 20:46:55 +0200 Subject: [PATCH 27/42] Update utils_helpers.py --- cmsplugin_cascade/utils_helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmsplugin_cascade/utils_helpers.py b/cmsplugin_cascade/utils_helpers.py index bcbbade01..68cd8720a 100644 --- a/cmsplugin_cascade/utils_helpers.py +++ b/cmsplugin_cascade/utils_helpers.py @@ -52,7 +52,7 @@ def get_qs_pages_public(): try: name_page_public = [str(page_url.page) for page_url in CMSSitemap().items()[:15]] queryset = Page.objects.filter(pagecontent_set__title__in=name_page_public) - except Page.DoesNotExist: + except OperationalError: #intial empty db queryset = Page.objects return queryset From ac2e97430f4c2bbb58cef97b03e34a831053ba26 Mon Sep 17 00:00:00 2001 From: Haricot Date: Sat, 24 Oct 2020 20:50:07 +0200 Subject: [PATCH 28/42] fix OperationError:no such table: django_site --- cmsplugin_cascade/utils_helpers.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cmsplugin_cascade/utils_helpers.py b/cmsplugin_cascade/utils_helpers.py index 68cd8720a..27ebd5f82 100644 --- a/cmsplugin_cascade/utils_helpers.py +++ b/cmsplugin_cascade/utils_helpers.py @@ -53,7 +53,6 @@ def get_qs_pages_public(): name_page_public = [str(page_url.page) for page_url in CMSSitemap().items()[:15]] queryset = Page.objects.filter(pagecontent_set__title__in=name_page_public) except OperationalError: - #intial empty db queryset = Page.objects return queryset From e09fc49e9ae86bb72fae74f49b38bd61e4f0220b Mon Sep 17 00:00:00 2001 From: Haricot Date: Sat, 24 Oct 2020 20:54:03 +0200 Subject: [PATCH 29/42] fix OperationError:no such table: django_site --- cmsplugin_cascade/utils_helpers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmsplugin_cascade/utils_helpers.py b/cmsplugin_cascade/utils_helpers.py index 27ebd5f82..817db4365 100644 --- a/cmsplugin_cascade/utils_helpers.py +++ b/cmsplugin_cascade/utils_helpers.py @@ -52,7 +52,8 @@ def get_qs_pages_public(): try: name_page_public = [str(page_url.page) for page_url in CMSSitemap().items()[:15]] queryset = Page.objects.filter(pagecontent_set__title__in=name_page_public) - except OperationalError: + except django.db.OperationalError: + #init db migrations queryset = Page.objects return queryset From 56de8c0a9c5b914d07728a9498fc961ea0f1e7ae Mon Sep 17 00:00:00 2001 From: Haricot Date: Sat, 24 Oct 2020 20:59:37 +0200 Subject: [PATCH 30/42] fix OperationError:no such table: django_site --- cmsplugin_cascade/utils_helpers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmsplugin_cascade/utils_helpers.py b/cmsplugin_cascade/utils_helpers.py index 817db4365..973dfd86b 100644 --- a/cmsplugin_cascade/utils_helpers.py +++ b/cmsplugin_cascade/utils_helpers.py @@ -1,5 +1,6 @@ from distutils.version import LooseVersion from django.conf import settings +from django.db import OperationalError from django.db.models import Q from cms import __version__ as CMS_VERSION from cms.models.pagemodel import Page @@ -52,7 +53,7 @@ def get_qs_pages_public(): try: name_page_public = [str(page_url.page) for page_url in CMSSitemap().items()[:15]] queryset = Page.objects.filter(pagecontent_set__title__in=name_page_public) - except django.db.OperationalError: + except OperationalError: #init db migrations queryset = Page.objects return queryset From d7dba70ec9912118c3365494ddfd57a25bb76b61 Mon Sep 17 00:00:00 2001 From: Haricot Date: Sun, 25 Oct 2020 09:06:05 +0100 Subject: [PATCH 31/42] wip update --- cmsplugin_cascade/models_base.py | 6 +++--- cmsplugin_cascade/plugin_base.py | 2 +- examples/pyproject.toml | 1 + tests/bootstrap4/test_container.py | 3 ++- tests/test_segmentation.py | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/cmsplugin_cascade/models_base.py b/cmsplugin_cascade/models_base.py index 1dfb65a78..d280198c2 100644 --- a/cmsplugin_cascade/models_base.py +++ b/cmsplugin_cascade/models_base.py @@ -1,5 +1,4 @@ from django.db import models -from django.utils import timezone from django.utils.html import mark_safe, format_html_join from django.utils.functional import cached_property import json @@ -111,7 +110,8 @@ def sanitize_related_siblings(self): """ if self.parent: plugins = self.__class__.objects.filter(id__in=self.parent._get_descendants_ids()) - [plugin.save() for plugin in plugins] + for plugin in plugins: + plugin.save() def sanitize_children(self): """ @@ -147,7 +147,7 @@ def save(self, sanitize_only=False, *args, **kwargs): def delete(self, *args, **kwargs): super().delete( *args, **kwargs) - sanitized = self.plugin_class.sanitize_related_siblings_model(self) + self.plugin_class.sanitize_related_siblings_model(self) @classmethod def _get_cascade_elements(cls): diff --git a/cmsplugin_cascade/plugin_base.py b/cmsplugin_cascade/plugin_base.py index 5f55f7ff0..f0c9c69f5 100644 --- a/cmsplugin_cascade/plugin_base.py +++ b/cmsplugin_cascade/plugin_base.py @@ -273,7 +273,7 @@ def get_identifier(cls, instance): return SafeText() @classmethod - def sanitize_model(cls, instance,sanitize_related_sibling=[]): + def sanitize_model(cls, instance,sanitize_related_sibling=None): """ This method is called, before the model is written to the database. It can be overloaded to sanitize the current models, in case a parent model changed in a way, which might diff --git a/examples/pyproject.toml b/examples/pyproject.toml index 0bfadcaeb..5ad0c6665 100644 --- a/examples/pyproject.toml +++ b/examples/pyproject.toml @@ -12,6 +12,7 @@ python = "^3.8" django = "*" django-cms = { git = "https://github.com/django-cms/django-cms", branch="release/4.0.x" } djangocms-alias = { git = "https://github.com/divio/djangocms-alias", branch="master" } +djangocms-ckeditor = { git = "https://github.com/django-cms/djangocms-text-ckeditor", branch="support/4.0.x" } djangocms-cascade = "*" django-compressor = "*" django-filer = "*" diff --git a/tests/bootstrap4/test_container.py b/tests/bootstrap4/test_container.py index f389e4fda..1e20b65fe 100644 --- a/tests/bootstrap4/test_container.py +++ b/tests/bootstrap4/test_container.py @@ -27,6 +27,7 @@ def test_edit_bootstrap_container(rf, bootstrap_container): assert 'fluid' in container_model.glossary assert str(container_model) == "for Landscape Phones, Tablets" + @pytest.mark.django_db def test_edit_bootstrap_row(rf, bootstrap_row): row_plugin, row_model = bootstrap_row @@ -41,7 +42,7 @@ def test_edit_bootstrap_row(rf, bootstrap_row): plugin_list = [container_model, row_model] # we now should have three columns attached to the row - assert len(list(row_model.get_descendants())) == 3 + assert row_model._get_descendant_count() == 3 for cms_plugin in row_model.get_descendants(): column_model, column_plugin = cms_plugin.get_plugin_instance() assert isinstance(column_model, CascadeElement) diff --git a/tests/test_segmentation.py b/tests/test_segmentation.py index 18ab7b745..546d703db 100644 --- a/tests/test_segmentation.py +++ b/tests/test_segmentation.py @@ -7,10 +7,10 @@ from django.contrib.auth import get_user_model from cms.api import add_plugin -from cmsplugin_cascade.utils_helpers import get_plugins_as_layered_tree from djangocms_text_ckeditor.cms_plugins import TextPlugin from cmsplugin_cascade.generic.simple_wrapper import SimpleWrapperPlugin from cmsplugin_cascade.segmentation.cms_plugins import SegmentPlugin +from cmsplugin_cascade.utils_helpers import get_plugins_as_layered_tree from .test_base import CascadeTestCase From 08c7a01a4edf79bd2343ad10af7dafe881af0275 Mon Sep 17 00:00:00 2001 From: Haricot Date: Sun, 25 Oct 2020 09:13:31 +0100 Subject: [PATCH 32/42] update bootstrap4/test_container.py --- tests/bootstrap4/test_container.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bootstrap4/test_container.py b/tests/bootstrap4/test_container.py index 1e20b65fe..0f535bf94 100644 --- a/tests/bootstrap4/test_container.py +++ b/tests/bootstrap4/test_container.py @@ -42,7 +42,7 @@ def test_edit_bootstrap_row(rf, bootstrap_row): plugin_list = [container_model, row_model] # we now should have three columns attached to the row - assert row_model._get_descendant_count() == 3 + assert len(row_model.get_descendant().values_list('id')) == 3 for cms_plugin in row_model.get_descendants(): column_model, column_plugin = cms_plugin.get_plugin_instance() assert isinstance(column_model, CascadeElement) From e198b8e2412d4050e1f7da43331bcdf1dae6f46f Mon Sep 17 00:00:00 2001 From: Haricot Date: Sun, 25 Oct 2020 09:16:17 +0100 Subject: [PATCH 33/42] update bootstrap4/test_container.py --- tests/bootstrap4/test_container.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bootstrap4/test_container.py b/tests/bootstrap4/test_container.py index 0f535bf94..c665a2329 100644 --- a/tests/bootstrap4/test_container.py +++ b/tests/bootstrap4/test_container.py @@ -42,7 +42,7 @@ def test_edit_bootstrap_row(rf, bootstrap_row): plugin_list = [container_model, row_model] # we now should have three columns attached to the row - assert len(row_model.get_descendant().values_list('id')) == 3 + assert len(row_model.get_descendants().values_list('id')) == 3 for cms_plugin in row_model.get_descendants(): column_model, column_plugin = cms_plugin.get_plugin_instance() assert isinstance(column_model, CascadeElement) From c7d64ad6232d6e73dab08dddea580ddb060c8e2a Mon Sep 17 00:00:00 2001 From: Haricot Date: Sun, 25 Oct 2020 09:19:30 +0100 Subject: [PATCH 34/42] update cmsplugin_cascade/utils_helpers.py --- cmsplugin_cascade/utils_helpers.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cmsplugin_cascade/utils_helpers.py b/cmsplugin_cascade/utils_helpers.py index 973dfd86b..998bbf838 100644 --- a/cmsplugin_cascade/utils_helpers.py +++ b/cmsplugin_cascade/utils_helpers.py @@ -1,5 +1,4 @@ from distutils.version import LooseVersion -from django.conf import settings from django.db import OperationalError from django.db.models import Q from cms import __version__ as CMS_VERSION From ab29db6898666e9c52756c41accae9059882e574 Mon Sep 17 00:00:00 2001 From: Haricot Date: Sun, 25 Oct 2020 13:45:24 +0100 Subject: [PATCH 35/42] update wip --- cmsplugin_cascade/bootstrap4/container.py | 1 + cmsplugin_cascade/models_base.py | 6 ++++-- cmsplugin_cascade/plugin_base.py | 8 +++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/cmsplugin_cascade/bootstrap4/container.py b/cmsplugin_cascade/bootstrap4/container.py index 79d56fe89..c4219735d 100644 --- a/cmsplugin_cascade/bootstrap4/container.py +++ b/cmsplugin_cascade/bootstrap4/container.py @@ -330,6 +330,7 @@ class Meta: def save_model(self, request, obj, form, change): super().save_model(request, obj, form, change) obj.sanitize_children() + obj.sanitize_related_siblings() def sanitize_related_siblings_model(self): self.sanitize_related_siblings() diff --git a/cmsplugin_cascade/models_base.py b/cmsplugin_cascade/models_base.py index d280198c2..c4d48e093 100644 --- a/cmsplugin_cascade/models_base.py +++ b/cmsplugin_cascade/models_base.py @@ -110,8 +110,10 @@ def sanitize_related_siblings(self): """ if self.parent: plugins = self.__class__.objects.filter(id__in=self.parent._get_descendants_ids()) - for plugin in plugins: - plugin.save() + for i in plugins: + if i.plugin_class.require_parent or i.plugin_class.parent_classes: + i.save() + return True def sanitize_children(self): """ diff --git a/cmsplugin_cascade/plugin_base.py b/cmsplugin_cascade/plugin_base.py index f0c9c69f5..43f44f025 100644 --- a/cmsplugin_cascade/plugin_base.py +++ b/cmsplugin_cascade/plugin_base.py @@ -287,9 +287,15 @@ def sanitize_model(cls, instance,sanitize_related_sibling=None): @classmethod def sanitize_related_siblings_model(cls, instance): + """ + This method is called, after the model is written to the database. It can be overloaded + to sanitize the current related siblings models, in case a require_parent or parent_classes is in plugin, + which might affect these related siblings plugin. + This method shall return `True`, in case a model change was necessary, otherwise it shall + return `False` to prevent a useless database update. + """ return False - @classmethod def get_data_representation(cls, instance): """ From 8a68e74d755e51c365170b11908f80815d2f6db7 Mon Sep 17 00:00:00 2001 From: Haricot Date: Sun, 25 Oct 2020 13:58:56 +0100 Subject: [PATCH 36/42] fix error: cms compatibity version --- cmsplugin_cascade/bootstrap4/container.py | 5 +++-- cmsplugin_cascade/models_base.py | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cmsplugin_cascade/bootstrap4/container.py b/cmsplugin_cascade/bootstrap4/container.py index c4219735d..b739396cf 100644 --- a/cmsplugin_cascade/bootstrap4/container.py +++ b/cmsplugin_cascade/bootstrap4/container.py @@ -10,7 +10,7 @@ from cmsplugin_cascade import app_settings from cmsplugin_cascade.bootstrap4.grid import Breakpoint from cmsplugin_cascade.forms import ManageChildrenFormMixin -from cmsplugin_cascade.utils_helpers import get_ancestor +from cmsplugin_cascade.utils_helpers import CMS_, get_ancestor from .plugin_base import BootstrapPluginBase from . import grid @@ -330,7 +330,8 @@ class Meta: def save_model(self, request, obj, form, change): super().save_model(request, obj, form, change) obj.sanitize_children() - obj.sanitize_related_siblings() + if not CMS_: + obj.sanitize_related_siblings() def sanitize_related_siblings_model(self): self.sanitize_related_siblings() diff --git a/cmsplugin_cascade/models_base.py b/cmsplugin_cascade/models_base.py index c4d48e093..b03681629 100644 --- a/cmsplugin_cascade/models_base.py +++ b/cmsplugin_cascade/models_base.py @@ -149,7 +149,8 @@ def save(self, sanitize_only=False, *args, **kwargs): def delete(self, *args, **kwargs): super().delete( *args, **kwargs) - self.plugin_class.sanitize_related_siblings_model(self) + if not CMS_: + self.plugin_class.sanitize_related_siblings_model(self) @classmethod def _get_cascade_elements(cls): From 71513f970ec0d701b517f28cd5b56be034231b8a Mon Sep 17 00:00:00 2001 From: Haricot Date: Tue, 27 Oct 2020 14:53:22 +0100 Subject: [PATCH 37/42] fix case jumbotron is first --- cmsplugin_cascade/bootstrap4/container.py | 9 +++++++-- cmsplugin_cascade/utils_helpers.py | 3 ++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/cmsplugin_cascade/bootstrap4/container.py b/cmsplugin_cascade/bootstrap4/container.py index b739396cf..919cc626d 100644 --- a/cmsplugin_cascade/bootstrap4/container.py +++ b/cmsplugin_cascade/bootstrap4/container.py @@ -197,11 +197,16 @@ def choose_help_text(*phrases): else: return phrases[2] - container = get_ancestor(['BootstrapContainerPlugin'], + container = get_ancestor(['BootstrapContainerPlugin','BootstrapJumbotronPlugin'], _cms_initial_attributes=self._cms_initial_attributes, plugin=obj ).get_bound_plugin() - breakpoints = container.glossary['breakpoints'] + + if 'breakpoints' in container.glossary: + breakpoints = container.glossary['breakpoints'] + elif 'media_queries' in container.glossary: + #Case Jumbotron is first, its not has ancestor container + breakpoints = list(container.glossary['media_queries'].keys()) width_fields, offset_fields, reorder_fields, responsive_fields = {}, {}, {}, {} units = [ngettext_lazy("{} unit", "{} units", i).format(i) for i in range(0, 13)] diff --git a/cmsplugin_cascade/utils_helpers.py b/cmsplugin_cascade/utils_helpers.py index 998bbf838..597185ca3 100644 --- a/cmsplugin_cascade/utils_helpers.py +++ b/cmsplugin_cascade/utils_helpers.py @@ -71,7 +71,8 @@ def get_ancestor(list_plugins_name, plugin=False, _cms_initial_attributes=False) if _cms_initial_attributes and 'parent' in _cms_initial_attributes and _cms_initial_attributes['parent']: ancestor_plugin = _cms_initial_attributes['placeholder'].get_plugins().filter( plugin_type__in=list_plugins_name, - position__range=[0,_cms_initial_attributes['position']]).order_by('position')[0] + position__range=[0,_cms_initial_attributes['position']] + ).order_by('position')[0] else: ancestor_plugin = plugin.placeholder.get_plugins().filter( plugin_type__in=list_plugins_name, From e76c7d5e0cffffd7180b36478ff7fbb0440ecdb4 Mon Sep 17 00:00:00 2001 From: Haricot Date: Tue, 27 Oct 2020 17:28:22 +0100 Subject: [PATCH 38/42] wip update --- cmsplugin_cascade/bootstrap4/secondary_menu.py | 13 ++++++++++--- cmsplugin_cascade/utils_helpers.py | 2 +- examples/bs4demo/settings.py | 4 +++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/cmsplugin_cascade/bootstrap4/secondary_menu.py b/cmsplugin_cascade/bootstrap4/secondary_menu.py index 3e8d9bdb3..dd6263fb7 100644 --- a/cmsplugin_cascade/bootstrap4/secondary_menu.py +++ b/cmsplugin_cascade/bootstrap4/secondary_menu.py @@ -3,9 +3,12 @@ from django.utils.translation import gettext_lazy as _ from entangled.forms import EntangledModelFormMixin from cms.plugin_pool import plugin_pool -from cms.models.pagemodel import Page +#from cms.models.pagemodel import Page +from cms.models import Page, PageContent from .plugin_base import BootstrapPluginBase - +from cmsplugin_cascade.utils_helpers import CMS_ +from django.db.models import Q +from cms.sitemaps import CMSSitemap class SecondaryMenuFormMixin(EntangledModelFormMixin): page_id = ChoiceField( @@ -29,7 +32,11 @@ class Meta: entangled_fields = {'glossary': ['page_id', 'offset', 'limit']} def __init__(self, *args, **kwargs): - choices = [(p.reverse_id, str(p)) for p in Page.objects.filter(reverse_id__isnull=False, publisher_is_draft=False)] + if CMS_: + choices = [(p.reverse_id, str(p)) for p in Page.objects.filter(reverse_id__isnull=False, publisher_is_draft=False)] + else: + pages_id = [ p.id for p in CMSSitemap().items()] + choices = [(p.reverse_id, str(p)) for p in Page.objects.filter(reverse_id__isnull=False).filter(id__in=pages_id)] self.base_fields['page_id'].choices = choices super().__init__(*args, **kwargs) diff --git a/cmsplugin_cascade/utils_helpers.py b/cmsplugin_cascade/utils_helpers.py index 597185ca3..af0104f2a 100644 --- a/cmsplugin_cascade/utils_helpers.py +++ b/cmsplugin_cascade/utils_helpers.py @@ -53,7 +53,7 @@ def get_qs_pages_public(): name_page_public = [str(page_url.page) for page_url in CMSSitemap().items()[:15]] queryset = Page.objects.filter(pagecontent_set__title__in=name_page_public) except OperationalError: - #init db migrations + # can happen if database is not ready yet queryset = Page.objects return queryset diff --git a/examples/bs4demo/settings.py b/examples/bs4demo/settings.py index 2cd260dd8..349c882f5 100644 --- a/examples/bs4demo/settings.py +++ b/examples/bs4demo/settings.py @@ -148,6 +148,8 @@ LANGUAGES = ( ('en', 'English'), + ('de', 'Germany'), + ('fr', 'French'), ) LOGGING = { @@ -214,7 +216,7 @@ ) CMSPLUGIN_CASCADE = { - 'alien_plugins': ('TextPlugin', 'TextLinkPlugin',), + 'alien_plugins': ('TextPlugin', 'TextLinkPlugin', 'AliasPlugin'), 'plugins_with_sharables': { 'BootstrapImagePlugin': ('image_shapes', 'image_width_responsive', 'image_width_fixed', 'image_height', 'resize_options',), From 0f59a9943e684be7625b650b8c79e079a545f516 Mon Sep 17 00:00:00 2001 From: Haricot Date: Tue, 27 Oct 2020 18:25:43 +0100 Subject: [PATCH 39/42] Add Internationalisation for bs4demo --- examples/bs4demo/urls.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/examples/bs4demo/urls.py b/examples/bs4demo/urls.py index 416b73531..45031da9c 100644 --- a/examples/bs4demo/urls.py +++ b/examples/bs4demo/urls.py @@ -4,6 +4,7 @@ from django.conf.urls.static import static from django.contrib import admin from django.views.generic import TemplateView +from django.conf.urls.i18n import i18n_patterns class CascadeDemoView(TemplateView): template_name = 'bs4demo/strides.html' @@ -11,10 +12,17 @@ class CascadeDemoView(TemplateView): admin.autodiscover() -urlpatterns = [ +urlpatterns = [] +i18n_urls = [ path('admin/select2/', include('django_select2.urls')), path('admin/', admin.site.urls), path('cascade/', CascadeDemoView.as_view()), path('', include('cms.urls')), ] + +if settings.USE_I18N: + urlpatterns.extend(i18n_patterns(*i18n_urls)) +else: + urlpatterns.extend(i18n_urls) + urlpatterns.extend(static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)) From 7d88fe040961257b334631204b76c49ccb7ef46d Mon Sep 17 00:00:00 2001 From: Haricot Date: Wed, 28 Oct 2020 10:27:43 +0100 Subject: [PATCH 40/42] update travis.yml --- .travis.yml | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index a743aedc3..cad521be5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,27 +2,19 @@ dist: focal language: python python: -# - 3.5 -# - 3.6 -# - 3.7 - 3.8 env: - # - DJANGOVER=django21 CMSVER=cms36 - # - DJANGOVER=django22 CMSVER=cms36 + - DJANGOVER=django22 CMSVER=cms37 -# - DJANGOVER=django30 CMSVER=cms37 + - DJANGOVER=django30 CMSVER=cms37 - DJANGOVER=django22 CMSVER=cms40 -# - DJANGOVER=django30 CMSVER=cms40 + - DJANGOVER=django30 CMSVER=cms40 -#matrix: -# allow_failures: -# - python: 3.8 -# env: DJANGOVER=django21 CMSVER=cms36 -# - python: 3.8 -# env: DJANGOVER=django22 CMSVER=cms36 -# - python: 3.8 -# env: DJANGOVER=django30 CMSVER=cms37 +matrix: + allow_failures: + - python: 3.8 + env: DJANGOVER=django30 CMSVER=cms37 install: - pip install tox From d3295e71cb583821287e2dff605e13309ecb0a1d Mon Sep 17 00:00:00 2001 From: Haricot Date: Wed, 28 Oct 2020 10:55:15 +0100 Subject: [PATCH 41/42] fix import order --- cmsplugin_cascade/bootstrap4/secondary_menu.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cmsplugin_cascade/bootstrap4/secondary_menu.py b/cmsplugin_cascade/bootstrap4/secondary_menu.py index dd6263fb7..cb0a38130 100644 --- a/cmsplugin_cascade/bootstrap4/secondary_menu.py +++ b/cmsplugin_cascade/bootstrap4/secondary_menu.py @@ -3,11 +3,9 @@ from django.utils.translation import gettext_lazy as _ from entangled.forms import EntangledModelFormMixin from cms.plugin_pool import plugin_pool -#from cms.models.pagemodel import Page -from cms.models import Page, PageContent -from .plugin_base import BootstrapPluginBase +from cms.models import Page from cmsplugin_cascade.utils_helpers import CMS_ -from django.db.models import Q +from .plugin_base import BootstrapPluginBase from cms.sitemaps import CMSSitemap class SecondaryMenuFormMixin(EntangledModelFormMixin): From 3873118b37dc369be36e76edcfd782801486edb6 Mon Sep 17 00:00:00 2001 From: Haricot Date: Wed, 28 Oct 2020 10:55:50 +0100 Subject: [PATCH 42/42] fix import order --- cmsplugin_cascade/bootstrap4/secondary_menu.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmsplugin_cascade/bootstrap4/secondary_menu.py b/cmsplugin_cascade/bootstrap4/secondary_menu.py index cb0a38130..9d659e639 100644 --- a/cmsplugin_cascade/bootstrap4/secondary_menu.py +++ b/cmsplugin_cascade/bootstrap4/secondary_menu.py @@ -4,9 +4,9 @@ from entangled.forms import EntangledModelFormMixin from cms.plugin_pool import plugin_pool from cms.models import Page +from cms.sitemaps import CMSSitemap from cmsplugin_cascade.utils_helpers import CMS_ from .plugin_base import BootstrapPluginBase -from cms.sitemaps import CMSSitemap class SecondaryMenuFormMixin(EntangledModelFormMixin): page_id = ChoiceField(