Add structure of CommentPanel to initialize the comment app in the frontend, and add forms to validate comments on save. (Comments are not yet output or written to the db)

pull/7050/head
jacobtoppm 2020-11-27 17:01:57 +00:00 zatwierdzone przez Matt Westcott
rodzic 9a48221d66
commit 1ca48eb31f
9 zmienionych plików z 121 dodań i 13 usunięć

Wyświetl plik

@ -13,6 +13,8 @@ from django.utils.translation import gettext_lazy
from taggit.managers import TaggableManager
from wagtail.admin import compare, widgets
from wagtail.admin.forms.comments import CommentForm, CommentReplyForm
from wagtail.admin.templatetags.wagtailadmin_tags import user_display_name
from wagtail.core.fields import RichTextField
from wagtail.core.models import Page
from wagtail.core.utils import camelcase_to_underscore, resolve_model_string
@ -59,6 +61,7 @@ def get_form_for_model(
}
metaclass = type(form_class)
return metaclass(class_name, (form_class,), form_class_attrs)
@ -789,8 +792,65 @@ class PrivacyModalPanel(EditHandler):
)
class CommentPanel(EditHandler):
def required_formsets(self):
# add the comments formset
# we need to pass in the current user for validation on the formset
# this could alternatively be done on the page form itself if we added the
# comments formset there, but we typically only add fields via edit handlers
current_user = getattr(self.request, 'user', None)
class CommentReplyFormWithRequest(CommentReplyForm):
user = current_user
class CommentFormWithRequest(CommentForm):
user = current_user
class Meta:
formsets = {
'replies': {
'form': CommentReplyFormWithRequest
}
}
return {
'comments': {
'form': CommentFormWithRequest,
'fields': ['text', 'contentpath'],
}
}
template = "wagtailadmin/edit_handlers/comments/comment_panel.html"
js_template = "wagtailadmin/edit_handlers/comments/comment_panel.js"
declarations_template = "wagtailadmin/edit_handlers/comments/comment_declarations.html"
def html_declarations(self):
return render_to_string(self.declarations_template)
def render(self):
user = getattr(self.request, 'user', None)
comments_author = {
'id': user.pk,
'name': user_display_name(user)
} if user else None
panel = render_to_string(self.template, {
'self': self,
'comments_author': comments_author
})
js = self.render_js_init()
return widget_with_script(panel, js)
def render_js_init(self):
return mark_safe(render_to_string(self.js_template, {
'self': self,
}))
# Now that we've defined EditHandlers, we can set up wagtailcore.Page to have some.
Page.content_panels = [
CommentPanel(),
FieldPanel('title', classname="full title"),
]

Wyświetl plik

@ -0,0 +1,52 @@
from django.forms import ValidationError
from django.forms.formsets import DELETION_FIELD_NAME
from django.utils.translation import gettext as _
from .models import WagtailAdminModelForm
class CommentReplyForm(WagtailAdminModelForm):
user = None
class Meta:
fields = ('text',)
def clean(self):
cleaned_data = super().clean()
user = self.user
if self.instance.pk and self.instance.user != user:
# trying to edit someone else's comment reply
if any(field for field in self.changed_data):
# includes DELETION_FIELD_NAME, as users cannot delete each other's individual comment replies
# if deleting a whole thread, this should be done by deleting the parent Comment instead
self.add_error(None, error=ValidationError(_("You cannot edit another user's comment")))
return cleaned_data
def save(self, *args, **kwargs):
if not self.instance.pk:
self.instance.user = self.user
return super().save(*args, **kwargs)
class CommentForm(WagtailAdminModelForm):
"""
This is designed to be subclassed and have the user overidden to enable user-based validation within the edit handler system
"""
user = None
def clean(self):
cleaned_data = super().clean()
user = self.user
if self.instance.pk and self.instance.user != user:
# trying to edit someone else's comment
if any(field for field in self.changed_data if field != DELETION_FIELD_NAME):
# users can delete each other's base comments, as this is just the "resolve" action
self.add_error(None, error=ValidationError(_("You cannot edit another user's comment")))
return cleaned_data
def save(self, *args, **kwargs):
if not self.instance.pk:
self.instance.user = self.user
return super().save(*args, **kwargs)

Wyświetl plik

@ -114,7 +114,6 @@ class WagtailAdminPageForm(WagtailAdminModelForm):
self.parent_page = parent_page
def clean(self):
cleaned_data = super().clean()
if 'slug' in self.cleaned_data:
if not Page._slug_is_available(

Wyświetl plik

@ -0,0 +1,2 @@
{% load wagtailadmin_tags %}
<button type="button" id="comment-icon" data-annotation class="button button-secondary button-small u-hidden">{% icon name='comment' class_name='initial' %}</button>

Wyświetl plik

@ -0,0 +1,6 @@
{% load wagtailadmin_tags %}
<div>
<div id="comments"></div>
</div>
{{ comments_author|json_script:"comments-author" }}
<script src="{% versioned_static 'wagtailadmin/js/comments.js' %}"></script>

Wyświetl plik

@ -0,0 +1 @@
window.comments.initComments([]);

Wyświetl plik

@ -27,6 +27,4 @@
<script src="{% versioned_static 'wagtailadmin/js/workflow-status.js' %}"></script>
<script src="{% versioned_static 'wagtailadmin/js/lock-unlock-action.js' %}"></script>
<script src="{% versioned_static 'wagtailadmin/js/vendor/bootstrap-tooltip.js' %}"></script>
<script src="{% versioned_static 'wagtailadmin/js/comments.js' %}"></script>
{% hook_output 'insert_editor_js' %}

Wyświetl plik

@ -116,8 +116,6 @@
Additional HTML code that edit handlers define through 'html_declarations'. (Technically this isn't JavaScript, but it will generally be data that exists for JavaScript to work with...)
{% endcomment %}
{{ edit_handler.html_declarations }}
{{ comments_author|json_script:"comments-author" }}
<button type="button" id="comment-icon" data-annotation class="button button-secondary button-small u-hidden">{% icon name='comment' class_name='initial' %}</button>
<script>
$(function() {
@ -179,7 +177,4 @@
LockUnlockAction('{{ csrf_token|escapejs }}', '{% url 'wagtailadmin_pages:edit' page.id %}');
});
</script>
<script>
window.comments.initComments([]);
</script>
{% endblock %}

Wyświetl plik

@ -14,7 +14,6 @@ from django.views.generic.base import ContextMixin, TemplateResponseMixin, View
from wagtail.admin import messages
from wagtail.admin.action_menu import PageActionMenu
from wagtail.admin.templatetags.wagtailadmin_tags import user_display_name
from wagtail.admin.views.generic import HookResponseMixin
from wagtail.admin.views.pages.utils import get_valid_next_url_from_request
from wagtail.core.exceptions import PageClassNotFoundError
@ -533,10 +532,6 @@ class EditView(TemplateResponseMixin, ContextMixin, HookResponseMixin, View):
'publishing_will_cancel_workflow': self.workflow_tasks and getattr(settings, 'WAGTAIL_WORKFLOW_CANCEL_ON_PUBLISH', True),
'locale': None,
'translations': [],
'comments_author': {
'id': self.request.user.pk, # TODO: move into the comments widget/edit handler when created
'name': user_display_name(self.request.user)
},
})
if getattr(settings, 'WAGTAIL_I18N_ENABLED', False):