From 2458820e08187cb0788e09c60eceaaeb8e7f9e3b Mon Sep 17 00:00:00 2001 From: Donald Buczek Date: Sun, 8 Mar 2020 20:05:53 +0100 Subject: [PATCH 1/3] Add FormPage page type Add FormPage page type using [Wagtail Form Builder]. [Wagtail Form Builder]: https://docs.wagtail.io/en/v2.0/reference/contrib/forms/index.html --- mpicms/base/models.py | 32 +++++++++++++++++++- mpicms/templates/base/form_page.html | 22 ++++++++++++++ mpicms/templates/base/form_page_landing.html | 15 +++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 mpicms/templates/base/form_page.html create mode 100644 mpicms/templates/base/form_page_landing.html diff --git a/mpicms/base/models.py b/mpicms/base/models.py index 6bdc226..c6522cf 100644 --- a/mpicms/base/models.py +++ b/mpicms/base/models.py @@ -7,10 +7,15 @@ from wagtail.admin.edit_handlers import FieldPanel from wagtail.snippets.edit_handlers import SnippetChooserPanel from wagtail.snippets.models import register_snippet -from wagtail.admin.edit_handlers import StreamFieldPanel +from wagtail.admin.edit_handlers import ( + StreamFieldPanel, InlinePanel, MultiFieldPanel, FieldRowPanel, +) from wagtail.images.edit_handlers import ImageChooserPanel from wagtail.core.fields import StreamField from wagtail.search import index +from wagtail.contrib.forms.models import AbstractEmailForm, AbstractFormField +from wagtail.contrib.forms.edit_handlers import FormSubmissionsPanel +from modelcluster.fields import ParentalKey from mpicms.news.mixins import NewsMixin from mpicms.events.mixins import EventMixin @@ -137,3 +142,28 @@ def serve(self, request, *args, **kwargs): def serve_preview(self, request, mode_name): return ContactListView.as_view()(request) + +class FormField(AbstractFormField): + page = ParentalKey('FormPage', on_delete=models.CASCADE, related_name='form_fields') + +class FormPage(AbstractEmailForm, SideBarMixin, BasePage): + intro = RichTextField(blank=True) + thank_you_text = RichTextField(blank=True) + + content_panels = ( + AbstractEmailForm.content_panels + + [ + FormSubmissionsPanel(), + FieldPanel('intro', classname="full"), + InlinePanel('form_fields', label="Form fields"), + FieldPanel('thank_you_text', classname="full"), + MultiFieldPanel([ + FieldRowPanel([ + FieldPanel('from_address', classname="col6"), + FieldPanel('to_address', classname="col6"), + ]), + FieldPanel('subject'), + ], "Email"), + ] + + SideBarMixin.content_panels + ) diff --git a/mpicms/templates/base/form_page.html b/mpicms/templates/base/form_page.html new file mode 100644 index 0000000..57a5e42 --- /dev/null +++ b/mpicms/templates/base/form_page.html @@ -0,0 +1,22 @@ +{% extends 'base/page.html' %} + +{% load wagtailcore_tags static %} + +{% block head %} + {{ block.super }} +{% endblock %} + +{% block page_content %} +

{{ page.title }}

+ +
+ {{ page.intro|richtext }} +
+ {% csrf_token %} + + {{ form.as_table }} +
+ +
+
+{% endblock %} diff --git a/mpicms/templates/base/form_page_landing.html b/mpicms/templates/base/form_page_landing.html new file mode 100644 index 0000000..dd2bb69 --- /dev/null +++ b/mpicms/templates/base/form_page_landing.html @@ -0,0 +1,15 @@ +{% extends 'base/page.html' %} + +{% load wagtailcore_tags static %} + +{% block head %} + {{ block.super }} +{% endblock %} + +{% block page_content %} +

{{ page.title }}

+ +
+ {{ page.thank_you_text|richtext }} +
+{% endblock %} From 5dc3abb95bb7447d47a64d17451482d50bfac797 Mon Sep 17 00:00:00 2001 From: Donald Buczek Date: Sun, 8 Mar 2020 20:08:20 +0100 Subject: [PATCH 2/3] Add model translation for FormPage Add model translations for the FormPage but not yet for the FormField model, which doesn't work well, because the field name are translated along with the label and different sets of data would be saved depending on the user languages and different sets of data would be retrieved by the vsc export depending on the admin language. --- mpicms/base/translation.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/mpicms/base/translation.py b/mpicms/base/translation.py index 30530c7..1d247a9 100644 --- a/mpicms/base/translation.py +++ b/mpicms/base/translation.py @@ -7,7 +7,10 @@ from modeltranslation.translator import TranslationOptions from modeltranslation.decorators import register -from .models import WikiPage, RootPage, HomePage, FeaturedImage, PhonelistPage +from .models import ( + WikiPage, RootPage, HomePage, FeaturedImage, PhonelistPage, + FormPage, FormField, +) @register(FeaturedImage) @@ -43,3 +46,10 @@ class PhonelistPageTR(TranslationOptions): fields = ( ) +@register(FormPage) +class FormPageTR(TranslationOptions): + fields = ( + 'sidebar', + 'intro', + 'thank_you_text', + ) From d909f228019ebfa3252895bf163099a44d0c6bc2 Mon Sep 17 00:00:00 2001 From: Donald Buczek Date: Sun, 8 Mar 2020 20:09:41 +0100 Subject: [PATCH 3/3] Add migration for FormPage Create file with ./manage.py makemigrations --- .../migrations/0051_formfield_formpage.py | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 mpicms/base/migrations/0051_formfield_formpage.py diff --git a/mpicms/base/migrations/0051_formfield_formpage.py b/mpicms/base/migrations/0051_formfield_formpage.py new file mode 100644 index 0000000..5058fcd --- /dev/null +++ b/mpicms/base/migrations/0051_formfield_formpage.py @@ -0,0 +1,62 @@ +# Generated by Django 2.2.9 on 2020-03-08 19:09 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import modelcluster.fields +import wagtail.core.blocks +import wagtail.core.fields +import wagtail.snippets.blocks + + +class Migration(migrations.Migration): + + dependencies = [ + ('wagtailcore', '0041_group_collection_permissions_verbose_name_plural'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('base', '0050_auto_20200119_1857'), + ] + + operations = [ + migrations.CreateModel( + name='FormPage', + fields=[ + ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.Page')), + ('to_address', models.CharField(blank=True, help_text='Optional - form submissions will be emailed to these addresses. Separate multiple addresses by comma.', max_length=255, verbose_name='to address')), + ('from_address', models.CharField(blank=True, max_length=255, verbose_name='from address')), + ('subject', models.CharField(blank=True, max_length=255, verbose_name='subject')), + ('sidebar', wagtail.core.fields.StreamField([('editor', wagtail.core.blocks.RichTextBlock(features=['h4', 'h5', 'h6', 'bold', 'italic', 'link', 'document-link'], label='Editor')), ('contacts', wagtail.core.blocks.ListBlock(wagtail.core.blocks.StructBlock([('contact', wagtail.snippets.blocks.SnippetChooserBlock('personal.Contact', label='Contact')), ('information', wagtail.core.blocks.TextBlock(label='Information', required=False))]), icon='user', label='Contacts', template='base/blocks/contact_list_block.html'))], blank=True, verbose_name='Sidebar Content')), + ('sidebar_en', wagtail.core.fields.StreamField([('editor', wagtail.core.blocks.RichTextBlock(features=['h4', 'h5', 'h6', 'bold', 'italic', 'link', 'document-link'], label='Editor')), ('contacts', wagtail.core.blocks.ListBlock(wagtail.core.blocks.StructBlock([('contact', wagtail.snippets.blocks.SnippetChooserBlock('personal.Contact', label='Contact')), ('information', wagtail.core.blocks.TextBlock(label='Information', required=False))]), icon='user', label='Contacts', template='base/blocks/contact_list_block.html'))], blank=True, null=True, verbose_name='Sidebar Content')), + ('sidebar_de', wagtail.core.fields.StreamField([('editor', wagtail.core.blocks.RichTextBlock(features=['h4', 'h5', 'h6', 'bold', 'italic', 'link', 'document-link'], label='Editor')), ('contacts', wagtail.core.blocks.ListBlock(wagtail.core.blocks.StructBlock([('contact', wagtail.snippets.blocks.SnippetChooserBlock('personal.Contact', label='Contact')), ('information', wagtail.core.blocks.TextBlock(label='Information', required=False))]), icon='user', label='Contacts', template='base/blocks/contact_list_block.html'))], blank=True, null=True, verbose_name='Sidebar Content')), + ('intro', wagtail.core.fields.RichTextField(blank=True)), + ('intro_en', wagtail.core.fields.RichTextField(blank=True, null=True)), + ('intro_de', wagtail.core.fields.RichTextField(blank=True, null=True)), + ('thank_you_text', wagtail.core.fields.RichTextField(blank=True)), + ('thank_you_text_en', wagtail.core.fields.RichTextField(blank=True, null=True)), + ('thank_you_text_de', wagtail.core.fields.RichTextField(blank=True, null=True)), + ('subscribers', models.ManyToManyField(to=settings.AUTH_USER_MODEL)), + ], + options={ + 'abstract': False, + }, + bases=('wagtailcore.page',), + ), + migrations.CreateModel( + name='FormField', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('sort_order', models.IntegerField(blank=True, editable=False, null=True)), + ('label', models.CharField(help_text='The label of the form field', max_length=255, verbose_name='label')), + ('field_type', models.CharField(choices=[('singleline', 'Single line text'), ('multiline', 'Multi-line text'), ('email', 'Email'), ('number', 'Number'), ('url', 'URL'), ('checkbox', 'Checkbox'), ('checkboxes', 'Checkboxes'), ('dropdown', 'Drop down'), ('multiselect', 'Multiple select'), ('radio', 'Radio buttons'), ('date', 'Date'), ('datetime', 'Date/time'), ('hidden', 'Hidden field')], max_length=16, verbose_name='field type')), + ('required', models.BooleanField(default=True, verbose_name='required')), + ('choices', models.TextField(blank=True, help_text='Comma separated list of choices. Only applicable in checkboxes, radio and dropdown.', verbose_name='choices')), + ('default_value', models.CharField(blank=True, help_text='Default value. Comma separated values supported for checkboxes.', max_length=255, verbose_name='default value')), + ('help_text', models.CharField(blank=True, max_length=255, verbose_name='help text')), + ('page', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='form_fields', to='base.FormPage')), + ], + options={ + 'ordering': ['sort_order'], + 'abstract': False, + }, + ), + ]