Skip to content

Instantly share code, notes, and snippets.

@wottpal
Last active August 14, 2018 14:26
Show Gist options
  • Save wottpal/b39fe7d28a399302f0526cf02964f4e7 to your computer and use it in GitHub Desktop.
Save wottpal/b39fe7d28a399302f0526cf02964f4e7 to your computer and use it in GitHub Desktop.

Simple Contact-Form in Kirby 3

As a starting point I've used the latest Starterkit (Beta 4) combined with the core from the latest Nightly Build (18-08-06).

First, set email-properties in your config. I would recommend using a mail-service like Mailgun (via SMTP) because setting everything up on your own server is cumbersome, error-prone, and unsecure. But of course, it's up to you.

site/config/config.php:

<?php

return [

  'debug'  => true,

	'email' => [

	  'transport' => [
	    'type' => 'smtp',
	    'port' => 465,
	    'ssl' => true,
	    'host' => 'smtp.server.com',
	    // If authentification is needed
      	    'auth' => true,
	    'username' => '...',
	    'password' => '...',
	  ],

	  'presets' => [
	    'contact-form' => [
	      'template'=> 'contact-form',
	      'from'    => '[email protected]',
              // Replace this with your email
	      'to'    => '[email protected]',
	    ],
	  ]

  ]

];

Then we setup a contact template. Because that's already done in the Starterkit I've added a new section and put the actual form in a snippet.

site/templates/contact.php:

...

<section>

  <h2>Form</h2>

  <?php if(param('success')): ?>

    <!-- Success -->
    <p>Message successfully sent.</p>

  <?php elseif(isset($alerts) && $alerts): ?>

    <!-- Errors -->
    <p>Fix the following errors:
      <ul>
        <?php foreach($alerts as $alert): ?>
          <li><?= html($alert) ?></li>
        <?php endforeach ?>
      </ul>
    </p>

  <?php endif ?>

  <!-- Actual Form -->
  <?= snippet('contact-form') ?>

</section>

...

site/snippets/contact-form.php:

<form method="post">

  <div>
    <label for="name">Name</label><br>
    <input type="text" id="name" name="name" required autofocus>
  </div>

  <div>
    <label for="email">E-Mail</label><br>
    <input type="email" id="email" name="email" required>
  </div>

  <div>
    <label for="message">Message</label><br>
    <textarea id="message" name="message" required></textarea>
  </div>

  <button type="submit" name="submit" value="submit">Submit</button>

</form>

With the current size of the form a snippet does not really make sense but with more fields, classes and wrappers it'll propably become a beast, so I would recommend using a snippet ;)

The actual logic of the form lives inside a controller which must be named exactly like our template (contact).

site/controllers/contact.php:

<?php

return function($site, $pages, $page) {
  if(!get('submit')) return;

  $successUrl = url($page->url(), [ 'params' => 'success:true' ]);
  $alerts = null;

  // Gather form-data
  $form = kirby()->request()->data();

  // TODO
  // Validate form-data here..
  // Propably use `Kirby\Toolkit\V::input` here like suggested by @CelineDesign

  // Try to send the mail
  try {

    kirby()->email('contact-form', [
      'subject' => "Message by {$form['name']}",
      'replyTo' => $form['email'],
      'data' => [ 'form' => $form ]
    ]);

    go($successUrl);

  } catch (Exception $error) {
    return [ 'alerts' => [ $error ] ];
  }

};

And finally we need the actual email-templates which are going to be sent. We called it contact-form in the config so lets create two(!) files:

  • site/emails/contact-form.html.php
  • site/emails/contact-form.text.php

Within these templates you can write all the template-code you are used to and also use global objects like site() or kirby().

site/emails/contact-form.html.php:

<p>
  Name: <?= $form['name'] ?>
</p>

<p>
  E-Mail: <?= $form['email'] ?>
</p>

<p>
  Message: <?= $form['message'] ?>
</p>

site/emails/contact-form.text.php:

Name: <?= $form['name'] ?>

E-Mail: <?= $form['email'] ?>

Message: <?= $form['message'] ?>

What could be improved

  • Add a simple Honeypot
  • Add Form-Validation
  • Use JavaScript for a loading animation when the form gets send
  • Or make the form completely AJAXish
  • Send a second mail as a confirmation for the user..
  • Better form markup (for autocomplete and accessibility)
@mzur
Copy link

mzur commented Aug 10, 2018

If you want more features for your form, try Uniform. It's not ready for Kirby 3 yet but it will be soon 😉

@johannschopplich
Copy link

@mzur Really? I can't wait. That's awesome! 😃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment