You are here

Build a Blog in Drupal 8: Custom Contact Forms

This tutorial is part of the "Build a Blog in Drupal 8" series:

  1. Content types and Fields
  2. Adding Comments
  3. Using Views
  4. Managing Blocks
  5. Create and Manage Menus
  6. 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.

Fig 1.1

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".

Fig 1.0

2. Enter "Drupal question" into Label and enter in an email address into Recipients.

Fig 1.2

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.

Fig 1.3

You'll notice that the form already has a few default fields.

Each contact form will have the following:

  • Sender name
  • Sender email
  • Subject
  • Message
  • 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.

Fig 1.4

2. Click on "Add field", then select "List (text)" from "Add a new field" and add "Drupal version" to the Label field.

Fig 1.5

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

Fig 1.6

4. Finally, let's make the field mandatory by checking "Required field", then click "Save settings".

Fig 1.7

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:

Fig 1.8

Don't forget to click on Save.

Test Form

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.

Fig 1.9

If you view the form as an anonymous user then you'll see the full form.

Fig 1.10

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.

Fig 1.11

3. Now if you go to "/contact" you'll see the form we created.

Storing Submissions

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.

Fig 1.2

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.

Summary

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.

Resources

Links

Modules Mentioned

Ivan is the founder of Web Wash and spends most of his time consulting and writing about Drupal. He's been working with Drupal for 6 years and has successfully completed several large Drupal projects in Australia.

Connect: Twitter drupal.org LinkedIn

Comments

Hello,
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 ?
Thank you.

ivan's picture

Hi Kevin,

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.

\Drupal\contact\Controller\ContactController::contactSitePage

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.

Cheers, Ivan

Hi,

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.

/**
   * The form builder.
   *
   * @var \Drupal\Core\Form\FormBuilderInterface.
   */
  protected $formBuilder;
 
  /**
   * Constructs a new BlockForm plugin
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Form\FormBuilderInterface $formBuilder
   *   The form builder.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, FormBuilderInterface $formBuilder) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
   $this->formBuilder = $formBuilder;
  }
 
  /**
   * [email protected]}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('form_builder')
    );
  }
 
  /**
   * Implements \Drupal\block\BlockBase::build().
   */
  public function build() {
    $build = array();
 
    $build['form'] = $this->formBuilder->getForm('Add here your own route fore example \Drupal\name\Form\MyFormName');
 
	    return $build;
  }
}
ivan's picture

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.

ivan's picture

Hi Andrew,

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.

Hello Ivan

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 [email protected] Ivan
This is Klemens and I hate how this mail looks.
Best regards
Klemens

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 :)

Cheers
Klemens

ivan's picture

Hi Klemens,

To modify the mail look at using the hook_mail_alter (https://api.drupal.org/api/drupal/core%21core.api.php/function/hook_mail...).

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...

Add new comment

Recent Blog Posts

I’m happy to announce that a new section has been published on our "Build Edge-to-edge Sites using

You may have noticed that I haven't posted any tutorials over at WebWash for a while.

Today we released the last three videos for the series on integrating Twitter and Drupal.

Today we have released three new videos from the "Posting Tweets" chapter in our series on using the Twitter module.

Last week we released our brand new series on using the Twitter module.