From 425438acd18db7556d31462316d2d5d79c80241d Mon Sep 17 00:00:00 2001 From: Erwhann-Rouge Guilhem MAS-PAITRAULT Date: Wed, 11 Oct 2017 12:02:58 +0200 Subject: [PATCH 01/10] Added primitive hook to before_page_copy --- wagtail_modeltranslation/wagtail_hooks.py | 41 +++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/wagtail_modeltranslation/wagtail_hooks.py b/wagtail_modeltranslation/wagtail_hooks.py index b557bc6..cff218e 100644 --- a/wagtail_modeltranslation/wagtail_hooks.py +++ b/wagtail_modeltranslation/wagtail_hooks.py @@ -4,6 +4,8 @@ import json from six import iteritems +from django import forms +from django.shortcuts import render from django.conf import settings from django.conf.urls import url from django.http import HttpResponse, QueryDict @@ -20,7 +22,18 @@ except ImportError: from wagtail.wagtailcore import hooks from wagtail.wagtailcore.models import Page from wagtail.wagtailcore.rich_text import PageLinkHandler +from wagtail.wagtailadmin.forms import CopyForm +# Required for PatchedCopyForm +from django.utils.translation import ugettext as _ +from django.utils.translation import ugettext_lazy, ungettext + +# TODO: Already in wagtail, replace with proper import +def get_valid_next_url_from_request(request): + next_url = request.POST.get('next') or request.GET.get('next') + if not next_url or not is_safe_url(url=next_url, host=request.get_host()): + return '' + return next_url @hooks.register('insert_editor_js') def translated_slugs(): @@ -160,3 +173,31 @@ def register_localized_page_link_handler(): return "" return ('page', LocalizedPageLinkHandler) + +class PatchedCopyForm(CopyForm): + + def __init__(self, *args, **kwargs): + self.page = kwargs.pop('page') + self.user = kwargs.pop('user', None) + can_publish = kwargs.pop('can_publish') + super(CopyForm, self).__init__(*args, **kwargs) + + for language in ('fr', 'en'): + title_initial = self.page.title+"_"+language + title_label = "new_title_"+language + self.fields[title_label] = forms.SlugField(initial=title_initial, label=_("New title")) + slug_initial = self.page.slug+"_"+language + slug_label = "new_slug_"+language + self.fields[slug_label] = forms.SlugField(initial=slug_initial, label=_("New slug")) + +@hooks.register('before_copy_page') +def before_copy_page(request, page): + parent_page = page.get_parent() + can_publish = parent_page.permissions_for_user(request.user).can_publish_subpage() + form = PatchedCopyForm(request.POST or None, user=request.user, page=page, can_publish=can_publish) + next_url = get_valid_next_url_from_request(request) + return render(request, 'modeltranslation_copy.html', { + 'page': page, + 'form': form, + 'next': next_url + }) From 8a1a9eb94b35a82f450e23a92c345c5c5fe3c304 Mon Sep 17 00:00:00 2001 From: Erwhann-Rouge Guilhem MAS-PAITRAULT Date: Wed, 11 Oct 2017 12:06:20 +0200 Subject: [PATCH 02/10] Added copy form template to override the Wagtail one --- .../templates/modeltranslation_copy.html | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 wagtail_modeltranslation/templates/modeltranslation_copy.html diff --git a/wagtail_modeltranslation/templates/modeltranslation_copy.html b/wagtail_modeltranslation/templates/modeltranslation_copy.html new file mode 100644 index 0000000..6f3a2c6 --- /dev/null +++ b/wagtail_modeltranslation/templates/modeltranslation_copy.html @@ -0,0 +1,36 @@ +{% extends "wagtailadmin/base.html" %} +{% load i18n %} +{% block titletag %}{% blocktrans with title=page.get_admin_display_title %}Copy {{ title }}{% endblocktrans %}{% endblock %} +{% block content %} + {% trans "Copy" as copy_str %} + {% include "wagtailadmin/shared/header.html" with title=copy_str subtitle=page.get_admin_display_title icon="doc-empty-inverse" %} + +
+
+ {% csrf_token %} + +

Wagtail modeltranslation copy

+ +
    + {% include "wagtailadmin/shared/field_as_li.html" with field=form.new_title %} + {% include "wagtailadmin/shared/field_as_li.html" with field=form.new_slug %} + {% include "wagtailadmin/shared/field_as_li.html" with field=form.new_parent_page %} + + {% if form.copy_subpages %} + {% include "wagtailadmin/shared/field_as_li.html" with field=form.copy_subpages %} + {% endif %} + + {% if form.publish_copies %} + {% include "wagtailadmin/shared/field_as_li.html" with field=form.publish_copies %} + {% endif %} +
+ + +
+
+{% endblock %} + +{% block extra_js %} + {{ block.super }} + {% include "wagtailadmin/pages/_editor_js.html" %} +{% endblock %} From fe0cd4c0b6ed209a2af7a5e1dc30ef51106c1ece Mon Sep 17 00:00:00 2001 From: Erwhann-Rouge Guilhem MAS-PAITRAULT Date: Wed, 11 Oct 2017 14:10:51 +0200 Subject: [PATCH 03/10] Template now load titles and slugs fields in all languages --- .../templates/modeltranslation_copy.html | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/wagtail_modeltranslation/templates/modeltranslation_copy.html b/wagtail_modeltranslation/templates/modeltranslation_copy.html index 6f3a2c6..bf22544 100644 --- a/wagtail_modeltranslation/templates/modeltranslation_copy.html +++ b/wagtail_modeltranslation/templates/modeltranslation_copy.html @@ -9,12 +9,11 @@
{% csrf_token %} -

Wagtail modeltranslation copy

    - {% include "wagtailadmin/shared/field_as_li.html" with field=form.new_title %} - {% include "wagtailadmin/shared/field_as_li.html" with field=form.new_slug %} - {% include "wagtailadmin/shared/field_as_li.html" with field=form.new_parent_page %} + {% for field in form.visible_fields %} + {% include "wagtailadmin/shared/field_as_li.html" with field=field %} + {% endfor %} {% if form.copy_subpages %} {% include "wagtailadmin/shared/field_as_li.html" with field=form.copy_subpages %} From d630f9c988662ff2b5715e5f846136ef7ea606aa Mon Sep 17 00:00:00 2001 From: Erwhann-Rouge Guilhem MAS-PAITRAULT Date: Wed, 11 Oct 2017 16:51:59 +0200 Subject: [PATCH 04/10] Created new form to override Wagtail's CopyForm --- .../patch_wagtailadmin_forms.py | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 wagtail_modeltranslation/patch_wagtailadmin_forms.py diff --git a/wagtail_modeltranslation/patch_wagtailadmin_forms.py b/wagtail_modeltranslation/patch_wagtailadmin_forms.py new file mode 100644 index 0000000..a236119 --- /dev/null +++ b/wagtail_modeltranslation/patch_wagtailadmin_forms.py @@ -0,0 +1,101 @@ +# coding: utf-8 + +from django import forms +from django.utils.translation import ugettext as _ +from django.utils.translation import ugettext_lazy, ungettext +from wagtail.wagtailcore.models import Page +from wagtail.wagtailadmin import widgets +from wagtail.wagtailadmin.forms import CopyForm + + +class PatchedCopyForm(CopyForm): + def __init__(self, *args, **kwargs): + # CopyPage must be passed a 'page' kwarg indicating the page to be copied + self.page = kwargs.pop('page') + self.user = kwargs.pop('user', None) + can_publish = kwargs.pop('can_publish') + super(CopyForm, self).__init__(*args, **kwargs) + + #self.fields['new_title'] = forms.CharField(initial=self.page.title, label=_("New title")) + for language in ('fr', 'en'): + locale_title = "new_title_{}".format(language) + locale_label = "{} [{}]".format(_("New title"), language) + self.fields[locale_title] = forms.CharField(initial=self.page.title, label=locale_label) + + #self.fields['new_slug'] = forms.SlugField(initial=self.page.slug, label=_("New slug")) + for language in ('fr', 'en'): + locale_title = "new_slug_{}".format(language) + locale_label = "{} [{}]".format(_("New slug"), language) + self.fields[locale_title] = forms.CharField(initial=self.page.title, label=locale_label) + + self.fields['new_parent_page'] = forms.ModelChoiceField( + initial=self.page.get_parent(), + queryset=Page.objects.all(), + widget=widgets.AdminPageChooser(can_choose_root=True, user_perms='copy_to'), + label=_("New parent page"), + help_text=_("This copy will be a child of this given parent page.") + ) + pages_to_copy = self.page.get_descendants(inclusive=True) + subpage_count = pages_to_copy.count() - 1 + if subpage_count > 0: + self.fields['copy_subpages'] = forms.BooleanField( + required=False, initial=True, label=_("Copy subpages"), + help_text=ungettext( + "This will copy %(count)s subpage.", + "This will copy %(count)s subpages.", + subpage_count) % {'count': subpage_count}) + + if can_publish: + pages_to_publish_count = pages_to_copy.live().count() + if pages_to_publish_count > 0: + # In the specific case that there are no subpages, customise the field label and help text + if subpage_count == 0: + label = _("Publish copied page") + help_text = _("This page is live. Would you like to publish its copy as well?") + else: + label = _("Publish copies") + help_text = ungettext( + "%(count)s of the pages being copied is live. Would you like to publish its copy?", + "%(count)s of the pages being copied are live. Would you like to publish their copies?", + pages_to_publish_count) % {'count': pages_to_publish_count} + + self.fields['publish_copies'] = forms.BooleanField( + required=False, initial=True, label=label, help_text=help_text + ) + + def clean(self): + cleaned_data = super(CopyForm, self).clean() + + # Make sure the slug isn't already in use + #slug = cleaned_data.get('new_slug') + + # New parent page given in form or parent of source, if parent_page is empty + parent_page = cleaned_data.get('new_parent_page') or self.page.get_parent() + + # check if user is allowed to create a page at given location. + if not parent_page.permissions_for_user(self.user).can_add_subpage(): + self._errors['new_parent_page'] = self.error_class([ + _("You do not have permission to copy to page \"%(page_title)s\"") % {'page_title': parent_page.get_admin_display_title()} + ]) + + # Count the pages with the same slug within the context of our copy's parent page + for language in ('fr', 'en'): + locale_slug = "slug_{}".format(language) + slug = cleaned_data.get(locale_slug) + + if slug and parent_page.get_children().filter(slug=slug).count(): + self._errors['new_slug'] = self.error_class( + [_("This slug is already in use within the context of its parent page \"%s\"" % parent_page)] + ) + # The slug is no longer valid, hence remove it from cleaned_data + del cleaned_data['new_slug'] + + # Don't allow recursive copies into self + if cleaned_data.get('copy_subpages') and (self.page == parent_page or parent_page.is_descendant_of(self.page)): + self._errors['new_parent_page'] = self.error_class( + [_("You cannot copy a page into itself when copying subpages")] + ) + + return cleaned_data + + From 55fff643d3a8b5c736be8be6310933b8e25e83da Mon Sep 17 00:00:00 2001 From: Erwhann-Rouge Guilhem MAS-PAITRAULT Date: Wed, 11 Oct 2017 16:55:23 +0200 Subject: [PATCH 05/10] Patched copy view from wagtail in before_page_copy hook --- wagtail_modeltranslation/wagtail_hooks.py | 85 ++++++++++++++++------- 1 file changed, 61 insertions(+), 24 deletions(-) diff --git a/wagtail_modeltranslation/wagtail_hooks.py b/wagtail_modeltranslation/wagtail_hooks.py index cff218e..43b3c44 100644 --- a/wagtail_modeltranslation/wagtail_hooks.py +++ b/wagtail_modeltranslation/wagtail_hooks.py @@ -2,17 +2,15 @@ import json -from six import iteritems +from django.shortcuts import render, redirect -from django import forms -from django.shortcuts import render from django.conf import settings from django.conf.urls import url from django.http import HttpResponse, QueryDict from django.utils.html import escape, format_html, format_html_join from django.views.decorators.csrf import csrf_exempt -from wagtail_modeltranslation import settings as wmt_settings -from modeltranslation import settings as mt_settings +from django.utils.translation import ugettext as _ +from django.utils.translation import ugettext_lazy, ungettext try: from wagtail.core import hooks @@ -22,11 +20,12 @@ except ImportError: from wagtail.wagtailcore import hooks from wagtail.wagtailcore.models import Page from wagtail.wagtailcore.rich_text import PageLinkHandler -from wagtail.wagtailadmin.forms import CopyForm + +from wagtail.wagtailadmin import messages + +from .patch_wagtailadmin_forms import PatchedCopyForm # Required for PatchedCopyForm -from django.utils.translation import ugettext as _ -from django.utils.translation import ugettext_lazy, ungettext # TODO: Already in wagtail, replace with proper import def get_valid_next_url_from_request(request): @@ -174,30 +173,68 @@ def register_localized_page_link_handler(): return ('page', LocalizedPageLinkHandler) -class PatchedCopyForm(CopyForm): - - def __init__(self, *args, **kwargs): - self.page = kwargs.pop('page') - self.user = kwargs.pop('user', None) - can_publish = kwargs.pop('can_publish') - super(CopyForm, self).__init__(*args, **kwargs) - - for language in ('fr', 'en'): - title_initial = self.page.title+"_"+language - title_label = "new_title_"+language - self.fields[title_label] = forms.SlugField(initial=title_initial, label=_("New title")) - slug_initial = self.page.slug+"_"+language - slug_label = "new_slug_"+language - self.fields[slug_label] = forms.SlugField(initial=slug_initial, label=_("New slug")) - @hooks.register('before_copy_page') def before_copy_page(request, page): parent_page = page.get_parent() can_publish = parent_page.permissions_for_user(request.user).can_publish_subpage() form = PatchedCopyForm(request.POST or None, user=request.user, page=page, can_publish=can_publish) next_url = get_valid_next_url_from_request(request) + + if request.method == 'POST': + # Prefill parent_page in case the form is invalid (as prepopulated value for the form field, + # because ModelChoiceField seems to not fall back to the user given value) + parent_page = Page.objects.get(id=request.POST['new_parent_page']) + + if form.is_valid(): + # Receive the parent page (this should never be empty) + if form.cleaned_data['new_parent_page']: + parent_page = form.cleaned_data['new_parent_page'] + + if not page.permissions_for_user(request.user).can_copy_to(parent_page, + form.cleaned_data.get('copy_subpages')): + raise PermissionDenied + + # Re-check if the user has permission to publish subpages on the new parent + can_publish = parent_page.permissions_for_user(request.user).can_publish_subpage() + + update_attrs = {} + for language in ('fr', 'en'): + slug = "slug_{}".format(language) + title = "title_{}".format(language) + update_attrs[slug] = form.cleaned_data["new_{}".format(slug)] + update_attrs[title] = form.cleaned_data["new_{}".format(title)] + + # Copy the page + new_page = page.copy( + recursive=form.cleaned_data.get('copy_subpages'), + to=parent_page, + update_attrs=update_attrs, + keep_live=(can_publish and form.cleaned_data.get('publish_copies')), + user=request.user, + ) + + # Give a success message back to the user + if form.cleaned_data.get('copy_subpages'): + messages.success( + request, + _("Page '{0}' and {1} subpages copied.").format(page.get_admin_display_title(), new_page.get_descendants().count()) + ) + else: + messages.success(request, _("Page '{0}' copied.").format(page.get_admin_display_title())) + + for fn in hooks.get_hooks('after_copy_page'): + result = fn(request, page, new_page) + if hasattr(result, 'status_code'): + return result + + # Redirect to explore of parent page + if next_url: + return redirect(next_url) + return redirect('wagtailadmin_explore', parent_page.id) + return render(request, 'modeltranslation_copy.html', { 'page': page, 'form': form, 'next': next_url }) + From 88e5895c5b5f021426d647b03d71cd8eb00bbadf Mon Sep 17 00:00:00 2001 From: Erwhann-Rouge Guilhem MAS-PAITRAULT Date: Wed, 11 Oct 2017 17:42:12 +0200 Subject: [PATCH 06/10] Removed hardcoded language codes, replaced by settings.LANGUAGES --- .../patch_wagtailadmin_forms.py | 17 +++++++++-------- wagtail_modeltranslation/wagtail_hooks.py | 6 +++--- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/wagtail_modeltranslation/patch_wagtailadmin_forms.py b/wagtail_modeltranslation/patch_wagtailadmin_forms.py index a236119..8db173b 100644 --- a/wagtail_modeltranslation/patch_wagtailadmin_forms.py +++ b/wagtail_modeltranslation/patch_wagtailadmin_forms.py @@ -1,6 +1,7 @@ # coding: utf-8 from django import forms +from django.conf import settings from django.utils.translation import ugettext as _ from django.utils.translation import ugettext_lazy, ungettext from wagtail.wagtailcore.models import Page @@ -17,15 +18,15 @@ class PatchedCopyForm(CopyForm): super(CopyForm, self).__init__(*args, **kwargs) #self.fields['new_title'] = forms.CharField(initial=self.page.title, label=_("New title")) - for language in ('fr', 'en'): - locale_title = "new_title_{}".format(language) - locale_label = "{} [{}]".format(_("New title"), language) + for code, name in settings.LANGUAGES: + locale_title = "new_title_{}".format(code) + locale_label = "{} [{}]".format(_("New title"), code) self.fields[locale_title] = forms.CharField(initial=self.page.title, label=locale_label) #self.fields['new_slug'] = forms.SlugField(initial=self.page.slug, label=_("New slug")) - for language in ('fr', 'en'): - locale_title = "new_slug_{}".format(language) - locale_label = "{} [{}]".format(_("New slug"), language) + for code, name in settings.LANGUAGES: + locale_title = "new_slug_{}".format(code) + locale_label = "{} [{}]".format(_("New slug"), code) self.fields[locale_title] = forms.CharField(initial=self.page.title, label=locale_label) self.fields['new_parent_page'] = forms.ModelChoiceField( @@ -79,8 +80,8 @@ class PatchedCopyForm(CopyForm): ]) # Count the pages with the same slug within the context of our copy's parent page - for language in ('fr', 'en'): - locale_slug = "slug_{}".format(language) + for code, name in settings.LANGUAGES: + locale_slug = "slug_{}".format(code) slug = cleaned_data.get(locale_slug) if slug and parent_page.get_children().filter(slug=slug).count(): diff --git a/wagtail_modeltranslation/wagtail_hooks.py b/wagtail_modeltranslation/wagtail_hooks.py index 43b3c44..8f6e82b 100644 --- a/wagtail_modeltranslation/wagtail_hooks.py +++ b/wagtail_modeltranslation/wagtail_hooks.py @@ -198,9 +198,9 @@ def before_copy_page(request, page): can_publish = parent_page.permissions_for_user(request.user).can_publish_subpage() update_attrs = {} - for language in ('fr', 'en'): - slug = "slug_{}".format(language) - title = "title_{}".format(language) + for code, name in settings.LANGUAGES: + slug = "slug_{}".format(code) + title = "title_{}".format(code) update_attrs[slug] = form.cleaned_data["new_{}".format(slug)] update_attrs[title] = form.cleaned_data["new_{}".format(title)] From 07e0e98b479b7034b7ece4cacb62d2e7ef017546 Mon Sep 17 00:00:00 2001 From: Erwhann-Rouge Guilhem MAS-PAITRAULT Date: Wed, 11 Oct 2017 18:37:58 +0200 Subject: [PATCH 07/10] Use SlugField and old slug to fill new page slugs --- wagtail_modeltranslation/patch_wagtailadmin_forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wagtail_modeltranslation/patch_wagtailadmin_forms.py b/wagtail_modeltranslation/patch_wagtailadmin_forms.py index 8db173b..fc1cb5a 100644 --- a/wagtail_modeltranslation/patch_wagtailadmin_forms.py +++ b/wagtail_modeltranslation/patch_wagtailadmin_forms.py @@ -27,7 +27,7 @@ class PatchedCopyForm(CopyForm): for code, name in settings.LANGUAGES: locale_title = "new_slug_{}".format(code) locale_label = "{} [{}]".format(_("New slug"), code) - self.fields[locale_title] = forms.CharField(initial=self.page.title, label=locale_label) + self.fields[locale_title] = forms.SlugField(initial=self.page.slug, label=locale_label) self.fields['new_parent_page'] = forms.ModelChoiceField( initial=self.page.get_parent(), From 3034d5807c7782062d17cad52d61b52ed0a66490 Mon Sep 17 00:00:00 2001 From: Erwhann-Rouge Guilhem MAS-PAITRAULT Date: Wed, 11 Oct 2017 18:44:34 +0200 Subject: [PATCH 08/10] Corrected template rendering "can publish" field twice --- wagtail_modeltranslation/templates/modeltranslation_copy.html | 4 ---- 1 file changed, 4 deletions(-) diff --git a/wagtail_modeltranslation/templates/modeltranslation_copy.html b/wagtail_modeltranslation/templates/modeltranslation_copy.html index bf22544..b63e610 100644 --- a/wagtail_modeltranslation/templates/modeltranslation_copy.html +++ b/wagtail_modeltranslation/templates/modeltranslation_copy.html @@ -18,10 +18,6 @@ {% if form.copy_subpages %} {% include "wagtailadmin/shared/field_as_li.html" with field=form.copy_subpages %} {% endif %} - - {% if form.publish_copies %} - {% include "wagtailadmin/shared/field_as_li.html" with field=form.publish_copies %} - {% endif %}
From 6cbd98ee5490bc575f03e301e408550975c8a8e5 Mon Sep 17 00:00:00 2001 From: Miguel Silva Date: Fri, 6 Sep 2019 14:19:57 +0100 Subject: [PATCH 09/10] Fixed imports --- .../patch_wagtailadmin_forms.py | 15 +++++--- wagtail_modeltranslation/wagtail_hooks.py | 34 +++++++++---------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/wagtail_modeltranslation/patch_wagtailadmin_forms.py b/wagtail_modeltranslation/patch_wagtailadmin_forms.py index fc1cb5a..a12b345 100644 --- a/wagtail_modeltranslation/patch_wagtailadmin_forms.py +++ b/wagtail_modeltranslation/patch_wagtailadmin_forms.py @@ -4,9 +4,15 @@ from django import forms from django.conf import settings from django.utils.translation import ugettext as _ from django.utils.translation import ugettext_lazy, ungettext -from wagtail.wagtailcore.models import Page -from wagtail.wagtailadmin import widgets -from wagtail.wagtailadmin.forms import CopyForm + +try: + from wagtail.core.models import Page + from wagtail.admin import widgets + from wagtail.admin.forms import CopyForm +except ImportError: + from wagtail.wagtailcore.models import Page + from wagtail.wagtailadmin import widgets + from wagtail.wagtailadmin.forms import CopyForm class PatchedCopyForm(CopyForm): @@ -65,6 +71,7 @@ class PatchedCopyForm(CopyForm): ) def clean(self): + print('test') cleaned_data = super(CopyForm, self).clean() # Make sure the slug isn't already in use @@ -98,5 +105,5 @@ class PatchedCopyForm(CopyForm): ) return cleaned_data - + diff --git a/wagtail_modeltranslation/wagtail_hooks.py b/wagtail_modeltranslation/wagtail_hooks.py index 8f6e82b..bc4b45d 100644 --- a/wagtail_modeltranslation/wagtail_hooks.py +++ b/wagtail_modeltranslation/wagtail_hooks.py @@ -2,37 +2,34 @@ import json -from django.shortcuts import render, redirect - +from django.core.exceptions import PermissionDenied +from six import iteritems from django.conf import settings from django.conf.urls import url from django.http import HttpResponse, QueryDict +from django.shortcuts import redirect, render from django.utils.html import escape, format_html, format_html_join -from django.views.decorators.csrf import csrf_exempt from django.utils.translation import ugettext as _ -from django.utils.translation import ugettext_lazy, ungettext +from django.views.decorators.csrf import csrf_exempt +from wagtail_modeltranslation import settings as wmt_settings +from modeltranslation import settings as mt_settings + +from .patch_wagtailadmin_forms import PatchedCopyForm try: from wagtail.core import hooks from wagtail.core.models import Page from wagtail.core.rich_text.pages import PageLinkHandler + from wagtail.admin import messages + from wagtail.admin.views.pages import get_valid_next_url_from_request + except ImportError: from wagtail.wagtailcore import hooks from wagtail.wagtailcore.models import Page from wagtail.wagtailcore.rich_text import PageLinkHandler + from wagtail.wagtailadmin import messages + from wagtail.wagtailadmin.views.pages import get_valid_next_url_from_request -from wagtail.wagtailadmin import messages - -from .patch_wagtailadmin_forms import PatchedCopyForm - -# Required for PatchedCopyForm - -# TODO: Already in wagtail, replace with proper import -def get_valid_next_url_from_request(request): - next_url = request.POST.get('next') or request.GET.get('next') - if not next_url or not is_safe_url(url=next_url, host=request.get_host()): - return '' - return next_url @hooks.register('insert_editor_js') def translated_slugs(): @@ -173,6 +170,7 @@ def register_localized_page_link_handler(): return ('page', LocalizedPageLinkHandler) + @hooks.register('before_copy_page') def before_copy_page(request, page): parent_page = page.get_parent() @@ -217,7 +215,8 @@ def before_copy_page(request, page): if form.cleaned_data.get('copy_subpages'): messages.success( request, - _("Page '{0}' and {1} subpages copied.").format(page.get_admin_display_title(), new_page.get_descendants().count()) + _("Page '{0}' and {1} subpages copied.").format( + page.get_admin_display_title(), new_page.get_descendants().count()) ) else: messages.success(request, _("Page '{0}' copied.").format(page.get_admin_display_title())) @@ -237,4 +236,3 @@ def before_copy_page(request, page): 'form': form, 'next': next_url }) - From 86c4711e48eb9c88513386fac5521df8d41ed40b Mon Sep 17 00:00:00 2001 From: Miguel Silva Date: Fri, 6 Sep 2019 15:15:41 +0100 Subject: [PATCH 10/10] Raise ValidationError if save has errors --- .../patch_wagtailadmin_forms.py | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/wagtail_modeltranslation/patch_wagtailadmin_forms.py b/wagtail_modeltranslation/patch_wagtailadmin_forms.py index a12b345..38dbb26 100644 --- a/wagtail_modeltranslation/patch_wagtailadmin_forms.py +++ b/wagtail_modeltranslation/patch_wagtailadmin_forms.py @@ -2,8 +2,9 @@ from django import forms from django.conf import settings +from django.core.exceptions import ValidationError from django.utils.translation import ugettext as _ -from django.utils.translation import ugettext_lazy, ungettext +from django.utils.translation import ungettext try: from wagtail.core.models import Page @@ -71,39 +72,36 @@ class PatchedCopyForm(CopyForm): ) def clean(self): - print('test') cleaned_data = super(CopyForm, self).clean() # Make sure the slug isn't already in use - #slug = cleaned_data.get('new_slug') + # slug = cleaned_data.get('new_slug') # New parent page given in form or parent of source, if parent_page is empty parent_page = cleaned_data.get('new_parent_page') or self.page.get_parent() # check if user is allowed to create a page at given location. if not parent_page.permissions_for_user(self.user).can_add_subpage(): - self._errors['new_parent_page'] = self.error_class([ - _("You do not have permission to copy to page \"%(page_title)s\"") % {'page_title': parent_page.get_admin_display_title()} - ]) + raise ValidationError({ + 'new_parent_page': _("You do not have permission to copy to page \"%(page_title)s\"") % {'page_title': parent_page.get_admin_display_title()} + }) # Count the pages with the same slug within the context of our copy's parent page for code, name in settings.LANGUAGES: - locale_slug = "slug_{}".format(code) + locale_slug = "new_slug_{}".format(code) slug = cleaned_data.get(locale_slug) - if slug and parent_page.get_children().filter(slug=slug).count(): - self._errors['new_slug'] = self.error_class( - [_("This slug is already in use within the context of its parent page \"%s\"" % parent_page)] - ) - # The slug is no longer valid, hence remove it from cleaned_data - del cleaned_data['new_slug'] + param = 'slug_' + code + query = {param: slug} + if slug and parent_page.get_children().filter(**query).count(): + raise ValidationError({ + locale_slug: _("This slug is already in use within the context of its parent page \"%s\"" % parent_page) + }) # Don't allow recursive copies into self if cleaned_data.get('copy_subpages') and (self.page == parent_page or parent_page.is_descendant_of(self.page)): - self._errors['new_parent_page'] = self.error_class( - [_("You cannot copy a page into itself when copying subpages")] - ) + raise ValidationError({ + 'new_parent_page': _("You cannot copy a page into itself when copying subpages") + }) return cleaned_data - -