Tutorial Summary

Contact forms are an essential part of many websites. Wagtail gives us a lot of powerful features without having to do very much work. In this tutorial we're going to create a contact form and a contact form landing page. The contact form will have 3 completely custom fields that the content editor can manage on their own. We'll also explore the Forms feature in the Wagtail Admin.

Most websites have some type of contact form. Whether it's for support or some other reason, there's usually a way to get in touch with a websites maintainer.

Contact forms can be a hassle though. But in this tutorial I'll show you how to add an email form for your Wagtail site. It's super easy, and there are lots of goodies out of the box.

Settings

First things first, you'll need to make sure you have wagtail.contrib.forms in your INSTALLED_APPS

INSTALLED_APPS = [
    '...',
    'wagtail.contrib.forms',
    '..',
]
Models

Next you'll need to create two classes. One will handle the email fields, and one will be your actual Wagtail Page.

# Your models.py file
from django.db import models

from modelcluster.fields import ParentalKey
from wagtail.admin.edit_handlers import (
    FieldPanel,
    FieldRowPanel,
    InlinePanel,
    MultiFieldPanel
)
from wagtail.core.fields import RichTextField
from wagtail.contrib.forms.models import (
    AbstractEmailForm,
    AbstractFormField
)


class FormField(AbstractFormField):
    page = ParentalKey(
        'ContactPage',
        on_delete=models.CASCADE,
        related_name='form_fields',
    )


class ContactPage(AbstractEmailForm):

    template = "contact/contact_page.html"
    # This is the default path.
    # If ignored, Wagtail adds _landing.html to your template name
    landing_page_template = "contact/contact_page_landing.html"

    intro = RichTextField(blank=True)
    thank_you_text = RichTextField(blank=True)

    content_panels = AbstractEmailForm.content_panels + [
        FieldPanel('intro'),
        InlinePanel('form_fields', label='Form Fields'),
        FieldPanel('thank_you_text'),
        MultiFieldPanel([
            FieldRowPanel([
                FieldPanel('from_address', classname="col6"),
                FieldPanel('to_address', classname="col6"),
            ]),
            FieldPanel("subject"),
        ], heading="Email Settings"),
    ]

When you're done with that, make sure you run python manage.py makemigrations and python manage.py migrate

Templates

There are two templates you're going to work with.

  1. Your main contact page template, and
  2. The landing page template (landing page is the term used for "the form was submitted, show a different page")
# contact_page.html
{% extends 'base.html' %}
{% load wagtailcore_tags %}

{% block content %}
    <h1>{{ page.title }}</h1>
    <p>
        {{ self.intro|richtext }}
    </p>

    <form action="{% pageurl page %}" method="POST">
        {% csrf_token %}
        <ul>
            {{ form.as_ul }}
        </ul>

        <button type="submit">
            Submit Form
        </button>
    </form>
{% endblock %}
# contact_page_landing.html
{% extends 'base.html' %}
{% load wagtailcore_tags %}

{% block content %}
    <h1>{{ page.title }}</h1>
    <p>
        {{ self.thank_you_text|richtext }}
    </p>
{% endblock %}

Lastly you'll need to create a new Contact Page from inside the Wagtail Admin. Add the fields you'd like to display. And that's it!

The Git Commit

The full git commit can be found here: https://github.com/CodingForEverybody/learn-wagtail/commit/d67bc5659ca023c21d8a9f01d30604f6d67cd2d6. Note: the git commit has Bootstrap 4 styling in it, and the code above (in this tutorial) has all the BS4 styling stripped out.

Sign up for our newsletter

Get notified about new lessons :)


Our Sites