This tutorial is part of the “Build a Blog in Drupal 8” series:
- Content types and Fields
- Adding Comments
- Using Views
- Managing Blocks
- Create and Manage Menus
- Custom Contact Forms
In the last tutorial, we added a few menus to flesh out the site navigation. Let’s now build on this by creating a few contact forms.
In Drupal 7, the Contact module is used to create basic contact forms. When a user fills them out, an email is sent to configured email addresses.
One limitation in Drupal 7 is you can’t modify the fields on the form. You can create different categories but the form stays the same.
In Drupal 8, things have changed. Instead of having a single form, you can now create different contact form types. Following in good old Drupal tradition, these contact form types are fieldable. This means you can add any custom field to them and this let’s you create proper, albeit basic forms.
So in this tutorial, we’ll create a custom contact form called “Drupal question”. This form will be similar to the standard contact form but we’ll add an extra field called “Drupal version”. This will let the user select a version of Drupal from a drop-down list.
Let’s jump right in.
Standard Contact Form
A default form called “Website feedback” is created when you install Drupal using the Standard installation profile. This form is used as the basic site-wide contact form and a link is displayed in the footer.
When the form is filled out an email is sent to a designated email address.
Custom Contact Form
As mentioned in the introduction, contact forms in Drupal 8 are now fieldable. This is great because you can create custom forms directly in core without installing extra modules.
Let’s create our “Drupal question” form.
1. Go to Structure, “Contact forms” and click on “Add contact form”.
2. Enter “Drupal question” into Label and enter in an email address into Recipients.
Once the form has been filled out, scroll to the bottom and click on Save.
3. You should’ve been redirected back to the “Contact forms” page. Now click on “Drupal question” to see the form.
You’ll notice that the form already has a few default fields.
Each contact form will have the following:
- Sender name
- Sender email
- Send copy to sender
Even though these are the default fields, you can disable them from the “Manage form display” page so they won’t be shown.
Add Field to Custom Contact Form
In Drupal 8, contact forms are fieldable. So let’s add a drop-down list which let’s users select a Drupal version.
Adding fields to the contact form is the same as adding one to a content type or block type. If you know how to add fields to them, you’ll know how to add them to contact forms.
1. Go to Structure, “Contact forms” and click on “Manage fields” from the Edit drop-down.
2. Click on “Add field”, then select “List (text)” from “Add a new field” and add “Drupal version” to the Label field.
Then click on “Save and continue”.
3. Enter in the following values into “Allowed values list”. Then click on “Save field settings”.
drupal-8|Drupal 8 drupal-7|Drupal 7
4. Finally, let’s make the field mandatory by checking “Required field”, then click “Save settings”.
Configure Field Widgets
New in Drupal 8 is the separation between the field and its widget. I discuss the difference between fields and widgets in part one: “Build a Blog in Drupal 8: Content types and Fields“
Let’s now configure the field widgets which’ll be displayed on the form.
1. Click on the “Manage form display” tab.
2. Move “Drupal version” to the top, then disable “Subject” and “Send copy to sender”. You can disable them by dragging them into the “Disabled” area.
Once complete the page should look like the image below:
Don’t forget to click on Save.
Now go to the form by going to “/contact/drupal_question” and you should see the “Drupal version” drop-down list at the top.
If you’re logged in, the “Your name” and “Your email address” will be pre-populated.
If you view the form as an anonymous user then you’ll see the full form.
Site-wide Contact Form
Each form comes with its own unique URL. This URL is “/contact/[machine_name]”, or in our case it’s “/contact/drupal_question”.
Another thing you can do is configure a site-wide contact form. This form will be accessible via the general URL “/contact”. If you now go to “/contact” you’ll see the “Website feedback” form, this is the default functionality but it can be changed.
Let’s now point it to our “Drupal question” form.
1. Go to Structure, “Contact forms” and click on Edit in the “Drupal question” row.
2. Check “Make this the default form” then click on Save.
3. Now if you go to “/contact” you’ll see the form we created.
The Contact module in Drupal 8 and all other versions sent the submission as an email. It never stored it in the database.
If you needed to store submissions there was always Webform and Entityform in Drupal 7.
However, in Drupal 8 there’s a module called Contact Storage which stores the submissions in the database.
Configuring it is fairly simple. Just enable it and you’re good to go. All submissions will then be stored in the database.
Submissions can be viewed by going to Structure, “Contact forms” and click on the List tab.
Dealing with Spam
If you’re allowing anonymous users to submit contact forms then make sure you implement countermeasures to handle spam.
In Drupal 7, to combat spam you would start by configuring Honeypot and Mollom. Luckily, both modules have Drupal 8 version so make sure you set them up on your Drupal 8 site.
The Contact module in Drupal 8 is more powerful than any other version of Drupal. You can do a lot out-of-the-box because forms are now fieldable. But will it replace Webform or eForm (Entityform for Drupal 7)? No it won’t. If a client wants the ability to create survey style forms then Webform is still the number one choice. But if all you require is a basic contact form then look at using the Contact module.
- Contact Storage
- Entityform (Drupal 7 only)
12 thoughts on “Build a Blog in Drupal 8: Custom Contact Forms”
I am looking for a way to add a contact form on my home page.
I thought I would be able to do it in Structure > Block layout and then add a form under a specific region but that does not seem to work because a form can not be a block.
I tried the module “Form Block” but also it does not seem to be mature enough yet.
I am a frontend developer and do not know much about PhP, is there not any simple way to add a form to my home page ?
You can’t display the contact form in a block out-of-the-box in Drupal. I would have recommended “Form Block” but you’ve already tried it out.
If you can’t find a module, the only other option is to implement it using code. If you want to go down the rabbit hole and display it using code, then look at the following method.
You mention you don’t know much of PHP so sorry for sending you a code solution. But if you can’t find a module it’s the only way possible.
I have this code to let it work. Just enter your own route to it .Make your info.yml file. And follow the rules of making a module. You can also use it for your own created forms.
Thanks for the example.
I would recommend using the Contact Storage module to extend the core contact form. The Contact Storage module will allow you to create a new “Block Type” and you can choose contact form as the entity for this new block type. This then allows you to insert forms wherever you like as blocks. It also adds a nice view for reviewing form submissions.
On a related note, do you know how one can use a custom formatter and send the emailed message as HTML email? I find the plain text email that gets sent is less than optimum.
> On a related note, do you know how one can use a custom formatter and send the emailed message as HTML email? I find the plain text email that gets sent is less than optimum.
Regarding the custom formatter. I would recommend the “Custom Formatters” module (https://www.drupal.org/project/custom_formatters) but it hasn’t been ported to D8 yet. Best thing to do is create a formatter using code. Just search for it in google.
HTML emails can be sent in two ways: with code or a module. Normally I use mimemail for this: https://www.drupal.org/project/mimemail. But I haven’t tried it for D8. If the module doesn’t work you’ll need to implement it with code.
Do you know any way to alter the generated mails which are sent to the admin? The mails look very ugly on my drupal page. The form contents are just merged together. Let’s take your form as an example. The mail would look like:
Drupal 8Klemensklemens@mail.comHello Ivan
This is Klemens and I hate how this mail looks.
So as you can see, newlines in a textarea work perfectly, but input fields are not separated with a newline character.
I appreciate every help from you. Thanks 🙂
To modify the mail look at using the hook_mail_alter (https://api.drupal.org/api/drupal/core%21core.api.php/function/hook_mail_alter/8.2.x).
I’ve yet to modify the mail sent in Drupal 8, but I would start with the hook.
Also, check out this great tutorial about working with Drupal 8’s mail system: http://code.tutsplus.com/tutorials/using-and-extending-the-drupal-8-mail-api-part-1–cms-23419
I’ve been working with the Drupal 8 form system for about 3-4 mos., and recently implemented Ajax in one of my forms. This worked pretty well until recently, when I started logging 500 errors in the console if someone clicked the submit button in the form without adding information in required fields, as well as no on-screen error being presented to the user. Previously, an error would be displayed on the form stating that the fields could not be left empty. Do you know of any changes to Drupal’s core form or Ajax module that could cause the change in behavior?
I’m not aware of any specific changes to the form or AJAX system.
Did you update Drupal core before the problem started
In Drupal 8, how would you achieve Drupal 7’s Contact module functionality of having 1 main contact form with multiple categories with a different e-mail recipient(s) for each category?
If “website feedback” is selected, the submission goes to email@example.com
If “general info” is selected, the submission goes to firstname.lastname@example.org
Did a quick google search and found this module: Contact Emails (https://www.drupal.org/project/contact_emails).
Never used it but looks promising.