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'] ?>
- 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 Really? I can't wait. That's awesome! 😃