• Stars
    star
    293
  • Rank 141,748 (Top 3 %)
  • Language
    PHP
  • License
    MIT License
  • Created over 11 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Add a simple contact form to your Craft CMS site.

Contact Form for Craft CMS

This plugin allows you to add an email contact form to your website.

Requirements

This plugin requires Craft CMS 4.0 or later.

Installation

You can install this plugin from the Plugin Store or with Composer.

From the Plugin Store

Go to the Plugin Store in your project’s Control Panel and search for “Contact Form”. Then click on the “Install” button in its modal window.

With Composer

Open your terminal and run the following commands:

# go to the project directory
cd /path/to/my-project.test

# tell Composer to load the plugin
composer require craftcms/contact-form

# tell Craft to install the plugin
php craft plugin/install contact-form

Usage

Your contact form template can look something like this:

{% macro errorList(errors) %}
    {% if errors %}
        {{ ul(errors, {class: 'errors'}) }}
    {% endif %}
{% endmacro %}

{% set submission = submission ?? null %}

<form method="post" action="" accept-charset="UTF-8">
    {{ csrfInput() }}
    {{ actionInput('contact-form/send') }}
    {{ redirectInput('contact/thanks') }}

    <h3><label for="from-name">Your Name</label></h3>
    {{ input('text', 'fromName', submission.fromName ?? '', {
        id: 'from-name',
        autocomplete: 'name',
    }) }}
    {{ submission ? _self.errorList(submission.getErrors('fromName')) }}

    <h3><label for="from-email">Your Email</label></h3>
    {{ input('email', 'fromEmail', submission.fromEmail ?? '', {
        id: 'from-email',
        autocomplete: 'email',
    }) }}
    {{ submission ? _self.errorList(submission.getErrors('fromEmail')) }}

    <h3><label for="subject">Subject</label></h3>
    {{ input('text', 'subject', submission.subject ?? '', {
        id: 'subject',
    }) }}
    {{ submission ? _self.errorList(submission.getErrors('subject')) }}

    <h3><label for="message">Message</label></h3>
    {{ tag('textarea', {
        text: submission.message ?? '',
        id: 'message',
        name: 'message',
        rows: 10,
        cols: 40,
    }) }}
    {{ submission ? _self.errorList(submission.getErrors('message')) }}

    <button type="submit">Send</button>
</form>

The only required fields are fromEmail and message. Everything else is optional.

Redirecting after submit

If you have a redirect hidden input, the user will get redirected to it upon successfully sending the email. The following variables can be used within the URL/path you set:

  • {fromName}
  • {fromEmail}
  • {subject}

For example, if you wanted to redirect to a contact/thanks page and pass the sender’s name to it, you could set the input like this:

{{ redirectInput('contact/thanks?from={fromName}') }}

On your contact/thanks.html template, you can access that from parameter using craft.app.request.getQueryParam():

<p>Thanks for sending that in, {{ craft.app.request.getQueryParam('from') }}!</p>

Note that if you don’t include a redirect input, the current page will get reloaded.

Displaying flash messages

When a contact form is submitted, the plugin will set a notice or success flash message on the user session. You can display it in your template like this:

{% if craft.app.session.hasFlash('notice') %}
    <p class="message notice">{{ craft.app.session.getFlash('notice') }}</p>
{% elseif craft.app.session.hasFlash('error') %}
    <p class="message error">{{ craft.app.session.getFlash('error') }}</p>
{% endif %}

Adding additional fields

You can add additional fields to your form by splitting your message field into multiple fields, using an array syntax for the input names:

<h3><label for="message">Message</label></h3>
<textarea rows="10" cols="40" id="message" name="message[body]">{{ submission.message.body ?? '' }}</textarea>

<h3><label for="phone">Your phone number</label></h3>
<input id="phone" type="text" name="message[Phone]" value="">

<h3>What services are you interested in?</h3>
<label><input type="checkbox" name="message[Services][]" value="Design"> Design</label>
<label><input type="checkbox" name="message[Services][]" value="Development"> Development</label>
<label><input type="checkbox" name="message[Services][]" value="Strategy"> Strategy</label>
<label><input type="checkbox" name="message[Services][]" value="Marketing"> Marketing</label>

If you have a primary “Message” field, you should name it message[body], like in that example.

An email sent with the above form might result in the following message:

• Name: John Doe
• Email: [email protected]
• Phone: (555) 123-4567
• Services: Design, Development

Hey guys, I really loved this simple contact form (I'm so tired of agencies
asking for everything but my social security number up front), so I trust
you guys know a thing or two about usability.

I run a small coffee shop and we want to start attracting more freelancer-
types to spend their days working from our shop (and sipping fine coffee!).
A clean new website with lots of social media integration would probably
help us out quite a bit there. Can you help us with that?

Hope to hear from you soon.

Cathy Chino

By default, there’s no restriction on which keys can be included on message. You can limit which fields are allowed using the allowedMessageFields setting in config/contact-form.php:

<?php

return [
    'allowedMessageFields' => ['Phone', 'Services'],
];

Overriding plugin settings

If you create a config file in your config/ folder called contact-form.php, you can override the plugin’s settings in the Control Panel. Since that config file is fully multi-environment aware, this is a handy way to have different settings across multiple environments.

Here’s what that config file might look like along with a list of all of the possible values you can override.

<?php

return [
    'toEmail'             => '[email protected]',
    'prependSubject'      => '',
    'prependSender'       => '',
    'allowAttachments'    => false,
    'successFlashMessage' => 'Message sent!'
];

Dynamically adding email recipients

You can programmatically add email recipients from your template by adding a hidden input field named toEmail like so:

<input type="hidden" name="toEmail" value="{{ '[email protected]'|hash }}">

If you want to add multiple recipients, you can provide a comma separated list of emails like so:

<input type="hidden" name="toEmail" value="{{ '[email protected],[email protected]'|hash }}">

Then from your config/contact-form.php config file, you’ll need to add a bit of logic:

<?php

$config = [];
$request = Craft::$app->request;

if (
    !$request->getIsConsoleRequest() &&
    ($toEmail = $request->getValidatedBodyParam('toEmail')) !== null
) {
    $config['toEmail'] = $toEmail;
}

return $config;

In this example if toEmail does not exist or fails validation (it was tampered with), the plugin will fallback to the “To Email” defined in the plugin settings, so you must have that defined as well.

File attachments

If you would like your contact form to accept file attachments, follow these steps:

  1. Go to Settings → Contact Form in the Control Panel, and make sure the plugin is set to allow attachments.
  2. Make sure your opening HTML <form> tag contains enctype="multipart/form-data".
  3. Add a <input type="file" name="attachment"> to your form.
  4. If you want to allow multiple file attachments, use multiple <input type="file" name="attachment[]" multiple> inputs.

Ajax form submissions

You can optionally post contact form submissions over Ajax if you’d like. Just send a POST request to your site with all of the same data that would normally be sent:

$('#my-form').submit(function(ev) {
    // Prevent the form from actually submitting
    ev.preventDefault();

    // Send it to the server
    $.post({
        url: '/',
        dataType: 'json',
        data: $(this).serialize(),
        success: function(response) {
            $('#thanks').text(response.message).fadeIn();
        },
        error: function(jqXHR) {
          // The response body will be an object containing the following keys:
          // - `message` – A high level message for the response
          // - `submission` – An object containing data from the attempted submission
          // - `errors` – An object containing validation errors from the submission, indexed by attribute name
          alert(jqXHR.responseJSON.message);
        }
    });
});

The afterValidate event

Modules and plugins can be notified when a submission is being validated, providing their own custom validation logic, using the afterValidate event on the Submission model:

use craft\contactform\models\Submission;
use yii\base\Event;

// ...

Event::on(Submission::class, Submission::EVENT_AFTER_VALIDATE, function(Event $e) {
    /** @var Submission $submission */
    $submission = $e->sender;
    
    // Make sure that `message[Phone]` was filled in
    if (empty($submission->message['Phone'])) {
        // Add the error
        // (This will be accessible via `message.getErrors('message.phone')` in the template.)
        $submission->addError('message.phone', 'A phone number is required.');
    }
});

The beforeSend event

Modules and plugins can be notified right before a message is sent out to the recipients using the beforeSend event. This is also an opportunity to flag the message as spam, preventing it from getting sent:

use craft\contactform\events\SendEvent;
use craft\contactform\Mailer;
use yii\base\Event;

// ...

Event::on(Mailer::class, Mailer::EVENT_BEFORE_SEND, function(SendEvent $e) {
    $isSpam = // custom spam detection logic...

    if ($isSpam) {
        $e->isSpam = true;
    }
});

The afterSend event

Modules and plugins can be notified right after a message is sent out to the recipients using the afterSend event.

use craft\contactform\events\SendEvent;
use craft\contactform\Mailer;
use yii\base\Event;

// ...

Event::on(Mailer::class, Mailer::EVENT_AFTER_SEND, function(SendEvent $e) {
    // custom logic...
});

Using a “Honeypot” field

Support for the honeypot captcha technique to fight spam has been moved to a separate plugin that complements this one.

More Repositories

1

cms

Build bespoke content experiences with Craft.
PHP
3,213
star
2

happy-lager

Craft CMS demo site.
PLpgSQL
735
star
3

awesome

A collection of awesome Craft CMS plugins, articles, resources and shiny things.
526
star
4

element-api

Create a JSON API/Feed for your elements in Craft.
PHP
498
star
5

feed-me

Craft CMS plugin for importing entry data from XML, RSS or ATOM feeds—routine task or on-demand.
PHP
287
star
6

commerce

Fully integrated ecommerce for Craft CMS.
PHP
215
star
7

craft

Composer starter project for Craft CMS.
Twig
183
star
8

nitro

Speedy local dev environment for @craftcms.
Go
178
star
9

plugins

The master list of Craft 3-compatible plugins
107
star
10

guest-entries

Accept anonymous entry submissions with Craft.
PHP
106
star
11

docker

Craft CMS Docker images.
Dockerfile
102
star
12

redactor

Edit rich text content in Craft CMS using Redactor by Imperavi.
JavaScript
101
star
13

webhooks

Plugin for integrating Craft with Zapier and IFTTT.
PHP
84
star
14

generator

Scaffold new Craft CMS plugins, modules, and system components from the CLI
PHP
83
star
15

starter-blog

Blog starter site learning resource.
JavaScript
79
star
16

server-check

Craft CMS server requirements checker.
Hack
68
star
17

store-hours

Manage business hours with Craft CMS.
PHP
62
star
18

aws-s3

Amazon S3 volume type for Craft CMS.
PHP
60
star
19

gatsby-source-craft

Gatsby source plugin for Craft CMS.
TypeScript
54
star
20

spoke-and-chain

Craft CMS + Craft Commerce demo site.
Twig
54
star
21

phpstorm-settings

PhpStorm settings used for Craft CMS development.
50
star
22

anchors

Add anchor links to headings in your Craft CMS website content.
PHP
48
star
23

europa-museum

Craft CMS demo site.
SCSS
47
star
24

ckeditor

Edit rich text content in Craft CMS using CKEditor.
PHP
46
star
25

shopify

Synchronize and extend product data from your Shopify storefront.
PHP
45
star
26

apple-news

Publish your Craft CMS content with Apple News Format.
PHP
41
star
27

docs

Documentation for Craft CMS, Craft Commerce, and other official products.
JavaScript
38
star
28

commerce-stripe

Stripe payment gateway for Craft Commerce
PHP
30
star
29

plugin-installer

Composer installer for Craft CMS plugins.
PHP
28
star
30

mailgun

Mailgun mailer adapter for Craft CMS.
PHP
28
star
31

redactor-clips

Adds Redactor’s “Clips” plugin to Rich Text fields in Craft
PHP
27
star
32

simple-text

Simple textarea field type for Craft CMS.
JavaScript
27
star
33

contact-form-honeypot

Add a honeypot captcha to your Craft CMS contact form.
PHP
26
star
34

vue-asset

⛔️ DEPRECATED | Vue.js asset bundle for Craft 3 Beta
JavaScript
24
star
35

postmark

A Postmark mail adapter for Craft CMS.
PHP
20
star
36

rector

Rector rules for updating plugins and modules to Craft CMS 4.
PHP
19
star
37

digital-products

Sell digital products with Craft Commerce.
PHP
18
star
38

legacy-docs

The source documentation for Craft CMS
JavaScript
16
star
39

ecs

Easy Coding Standard configurations for Craft CMS projects.
PHP
16
star
40

oauth2-craftid

Craft ID Provider for OAuth 2.0 Client.
PHP
15
star
41

query

Run SQL queries as an admin from the Craft CMS control panel.
PHP
15
star
42

gatsby-helper

Craft CMS helper plugin for Gatsby.
PHP
15
star
43

fix-fks

Utility that restores any missing foreign key constraints
PHP
12
star
44

mandrill

Mandrill mailer adapter for Craft CMS.
PHP
12
star
45

phpstan

PHPStan configuration for Craft CMS projects.
12
star
46

google-cloud

Google Cloud Storage volume type for Craft CMS.
PHP
11
star
47

tutorial-project

Tutorial demo project source.
Twig
9
star
48

image

Container images that are used as the base for Craft CMS container applications
Dockerfile
8
star
49

sass

Sass mixins for the Craft CMS control panel.
SCSS
8
star
50

commerce-paypal

PayPal payment gateway for Craft Commerce.
PHP
6
star
51

commerce-omnipay

Omnipay gateway bridge for Craft Commerce
PHP
5
star
52

license

The Craft License
5
star
53

hexdec

Adds a ‘hexdec’ filter to Craft CMS.
PHP
5
star
54

commerce-paypal-checkout

PayPal Checkout gateway for Craft Commerce.
PHP
5
star
55

commerce-mollie

Mollie payment gateway for Craft Commerce.
PHP
5
star
56

.github

GitHub community files for Craft CMS.
5
star
57

ontherocks

JavaScript
5
star
58

stripe

Sync and extend Stripe products and subscriptions.
PHP
5
star
59

azure-blob

Azure Blob Storage for Craft CMS.
PHP
4
star
60

commerce-sagepay

SagePay payment gateway for Craft Commerce.
PHP
4
star
61

yii2-dynamodb

Yii2 implementation of a queue and cache driver for DynamoDB
PHP
4
star
62

automation-workshop

PLpgSQL
4
star
63

html-field

Base class for Craft CMS field types with HTML values.
PHP
4
star
64

cloud

Public repo for discussions, feature requests, and ehancements Craft Cloud. For support, please email [email protected]
4
star
65

legacy-commerce-docs

Commerce Documentation
JavaScript
4
star
66

flysystem

Flysystem integration package for Craft CMS 4
PHP
3
star
67

locales

Craft CMS localization data for all the locales.
PHP
3
star
68

commerce-eway

eWay payment gateway for Craft Commerce.
PHP
3
star
69

commerce-multisafepay

MultiSafepay payment gateway for Craft Commerce.
PHP
3
star
70

rackspace

Rackspace Cloud Files volume type for Craft CMS
PHP
2
star
71

commerce-paystack

Paystack payment gateway for Craft Commerce.
PHP
2
star
72

commerce-worldpay

Worldpay payment gateway for Craft Commerce.
PHP
2
star
73

plugin-port-helper

Plugin port helper for porting plugins from Craft 2 to Craft 3.
PHP
2
star
74

homebrew-nitro

Brew repository for Craft Nitro.
Ruby
2
star
75

commerce-taxjar

TaxJar integration for Craft Commerce.
PHP
2
star
76

docs-translations

Translated content moved out of `docs` and maintained separately.
JavaScript
1
star
77

textlint-rule-linkable-params

Custom textlint rule for allowing lowercase variations of terms when linked.
JavaScript
1
star
78

craftcms-imgproxy

PHP
1
star
79

console

Public repo for bug reports, discussions, feature requests, and ehancements Craft Console and the Plugin Store
1
star
80

ddev-craft-cloud

Shell
1
star