diff --git a/opentech/public/forms/__init__.py b/opentech/public/forms/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..bb2741c81da1f285a4da9406913764ca18223bf1 --- /dev/null +++ b/opentech/public/forms/__init__.py @@ -0,0 +1 @@ +default_app_config = 'opentech.public.forms.apps.FormsConfig' diff --git a/opentech/public/forms/apps.py b/opentech/public/forms/apps.py new file mode 100644 index 0000000000000000000000000000000000000000..71dfe9124852b4f28997515934e3d068178e41ac --- /dev/null +++ b/opentech/public/forms/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class FormsConfig(AppConfig): + name = 'opentech.public.forms' + label = 'public_forms' diff --git a/opentech/public/forms/migrations/0001_initial.py b/opentech/public/forms/migrations/0001_initial.py new file mode 100644 index 0000000000000000000000000000000000000000..7269e30cfb8cd61033240f4771b894bbf73111dc --- /dev/null +++ b/opentech/public/forms/migrations/0001_initial.py @@ -0,0 +1,62 @@ +# Generated by Django 2.0.9 on 2018-12-18 08:58 + +from django.db import migrations, models +import django.db.models.deletion +import modelcluster.fields +import wagtail.core.fields + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('wagtailcore', '0040_page_draft_title'), + ('images', '0003_customimage_drupal_id'), + ] + + operations = [ + 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')), + ], + options={ + 'ordering': ['sort_order'], + 'abstract': False, + }, + ), + 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')), + ('social_text', models.CharField(blank=True, max_length=255)), + ('listing_title', models.CharField(blank=True, help_text='Override the page title used when this page appears in listings', max_length=255)), + ('listing_summary', models.CharField(blank=True, help_text="The text summary used when this page appears in listings. It's also used as the description for search engines if the 'Search description' field above is not defined.", max_length=255)), + ('intro', wagtail.core.fields.RichTextField(blank=True)), + ('thank_you_text', wagtail.core.fields.RichTextField(blank=True)), + ('header_image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='images.CustomImage')), + ('listing_image', models.ForeignKey(blank=True, help_text='Choose the image you wish to be displayed when this page appears in listings', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='images.CustomImage')), + ('social_image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='images.CustomImage')), + ], + options={ + 'abstract': False, + }, + bases=('wagtailcore.page', models.Model), + ), + migrations.AddField( + model_name='formfield', + name='page', + field=modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='form_fields', to='public_forms.FormPage'), + ), + ] diff --git a/opentech/public/forms/migrations/__init__.py b/opentech/public/forms/migrations/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/opentech/public/forms/models.py b/opentech/public/forms/models.py new file mode 100644 index 0000000000000000000000000000000000000000..5e78ac05e545207f00cd78002c5374b749e05af6 --- /dev/null +++ b/opentech/public/forms/models.py @@ -0,0 +1,40 @@ +from django.db import models + +from modelcluster.fields import ParentalKey + +from wagtail.core.fields import RichTextField +from wagtail.admin.edit_handlers import ( + FieldPanel, FieldRowPanel, MultiFieldPanel, InlinePanel +) +from wagtail.contrib.forms.models import AbstractEmailForm, AbstractFormField +from wagtail.search import index + +from opentech.public.utils.models import BasePage + + +class FormField(AbstractFormField): + page = ParentalKey('FormPage', on_delete=models.CASCADE, related_name='form_fields') + + +class FormPage(AbstractEmailForm, BasePage): + subpage_types = [] + + intro = RichTextField(blank=True) + thank_you_text = RichTextField(blank=True) + + search_fields = BasePage.search_fields + [ + index.SearchField('intro'), + ] + + content_panels = AbstractEmailForm.content_panels + [ + 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"), + ] diff --git a/opentech/public/forms/templates/public_forms/form_page.html b/opentech/public/forms/templates/public_forms/form_page.html new file mode 100644 index 0000000000000000000000000000000000000000..1e5d2457427e5648edb4f3dcfadac64fd3884c47 --- /dev/null +++ b/opentech/public/forms/templates/public_forms/form_page.html @@ -0,0 +1,14 @@ +{% extends "base.html" %} +{% load wagtailcore_tags %} + +{% block content %} + <div> + <h1>{{ page.title }}</h1> + {{ page.intro|richtext }} + <form action="{% pageurl page %}" method="POST"> + {% csrf_token %} + {{ form.as_p }} + <input type="submit"> + </form> + </div> +{% endblock %} \ No newline at end of file diff --git a/opentech/public/forms/templates/public_forms/form_page_landing.html b/opentech/public/forms/templates/public_forms/form_page_landing.html new file mode 100644 index 0000000000000000000000000000000000000000..36a16a6475ae3916bab026ae12ba6fa58923a9e0 --- /dev/null +++ b/opentech/public/forms/templates/public_forms/form_page_landing.html @@ -0,0 +1,9 @@ +{% extends "base.html" %} +{% load wagtailcore_tags %} + +{% block content %} + <div> + <h1>Thank you</h1> + <div>{{ page.thank_you_text|richtext }}</div> + </div> +{% endblock %} diff --git a/opentech/public/utils/wagtail_hooks.py b/opentech/public/utils/wagtail_hooks.py index 51d7eb042495a8c5a31816cc8cab74d6b8896ce7..d59763000b689369cb3f6eb1a073f5e6f6ae1b78 100644 --- a/opentech/public/utils/wagtail_hooks.py +++ b/opentech/public/utils/wagtail_hooks.py @@ -22,9 +22,3 @@ class TaxonomiesModelAdminGroup(ModelAdminGroup): modeladmin_register(TaxonomiesModelAdminGroup) - - -# Hide forms from the side menu, remove if adding public.forms back in -@hooks.register('construct_main_menu') -def hide_snippets_menu_item(request, menu_items): - menu_items[:] = [item for item in menu_items if item.name != 'forms'] diff --git a/opentech/settings/base.py b/opentech/settings/base.py index 0fb1fac928d7d236080c582c1207a7f211cdb759..59d05d300f5f53030fc79e06d7bcfcebaf2ff7c0 100644 --- a/opentech/settings/base.py +++ b/opentech/settings/base.py @@ -83,6 +83,7 @@ INSTALLED_APPS = [ 'opentech.public.projects', 'opentech.public.search', 'opentech.public.standardpages', + 'opentech.public.forms', 'opentech.public.utils', 'social_django', diff --git a/vagrant/provision.sh b/vagrant/provision.sh index 2c64b99cf4f6c36cc5a812114aecf701144eb33e..47b296609d931d58dd1080cf2ba7aef275269179 100755 --- a/vagrant/provision.sh +++ b/vagrant/provision.sh @@ -63,4 +63,5 @@ su - vagrant -c "sudo apt-get install -y nodejs" # Build the static files su - vagrant -c "sudo npm install -g gulp-cli" +su - vagrant -c "cd $PROJECT_DIR; npm install" su - vagrant -c "cd $PROJECT_DIR; gulp deploy"