-
Notifications
You must be signed in to change notification settings - Fork 0
Contact form integration
This tutorial explains how you can pass the product or plan configuration to a contact form when the "request product"/"request plan" button is clicked.
For this tutorial we will use the Uniform plugin by Martin Zurowietz. If you already use a different plugin or prefer to use Kirby's core methods, you can adapt the code accordingly. If you want to follow the example, please first install the Uniform plugin as explained in its docs.
The example code from this tutorial treats the configuration data as optional, so you can use the same page as a general contact form.
First we will create a page controller for the form template. In this example we will call it site/controllers/form.php
.
The controller does all the heavy lifting. This includes setting up Uniform, getting the configuration data from the form and handling the form submission:
<?php
use Uniform\Form;
return function ($kirby) {
$form = new Form([
'email' => [
'rules' => ['required', 'email'],
'message' => 'Please enter a valid email address',
],
'message' => [
'rules' => ['required'],
'message' => 'Please enter a message',
],
'roomle-configuration' => []
]);
// get the configuration data from the request or
// fall back to the unescaped data from Uniform
$configurationData = $kirby->request()->get(
'roomle-configuration',
htmlspecialchars_decode($form->old('roomle-configuration'))
);
// turn the raw configuration string into a nice object structure;
// the plugin automatically handles both plan and product configurations
$plan = $configurationData ? roomlePlan($configurationData) : null;
// only submit the form if the `submit` value is set;
// just listening for POST requests won't work because the
// configuration data is also transmitted via a POST request
if ($kirby->request()->get('submit')) {
$form->emailAction([
'to' => 'me@example.com',
'from' => 'info@example.com',
// we'll use a custom plain text email template (see step 4)
'escapeHtml' => false,
'template' => 'roomle-contact'
]);
}
return compact('form', 'plan');
};
The controller passes two variables to our form template, $plan
with all the Roomle configuration data and $form
from Uniform.
We can now use these variables in site/templates/form.php
to display both the contact form and the product configuration:
<?php if ($plan && $url = $plan->configuratorUrl()): ?>
<a href="<?= esc($url, 'attr') ?>">Back to the configurator</a>
<?php endif ?>
<form action="<?= $page->url() ?>" method="POST">
<label for="email">Email address</label>
<input id="email" name="email" type="email" value="<?= $form->old('email') ?>">
<label for="email">Message</label>
<textarea id="message" name="message"><?= $form->old('message') ?></textarea>
<?= csrf_field() ?>
<?= honeypot_field() ?>
<?php if ($plan): ?>
<input name="roomle-configuration" type="hidden" value="<?= esc($plan->toJson(), 'attr') ?>">
<?php endif ?>
<input type="submit" name="submit" value="Submit">
</form>
<?php if ($form->success()): ?>
Success!
<?php else: ?>
<?php snippet('uniform/errors', ['form' => $form]) ?>
<?php endif ?>
<?php if ($plan): ?>
<h2>Configuration data</h2>
<?php if ($plan->hasId() === true): ?>
<?= $plan->thumbnail()->html(['class' => 'configuration-image']) ?>
<?php endif ?>
<?php foreach ($plan->groupedItems() as $item): ?>
<h3><?= esc($item->count()) ?>x <?= esc($item->label()) ?></h3>
<p><?= esc($item->size()) ?></p>
<?= $item->perspectiveImage()->html(['class' => 'configuration-image']) ?>
<table>
<tr>
<th>Count</th>
<th>Article number</th>
<th>Name</th>
</tr>
<?php foreach ($item->parts() as $part): ?>
<tr>
<td><?= esc($part->count()) ?></td>
<td><?= esc($part->articleNr()) ?></td>
<td>
<?= esc($part->label()) ?>
<dl class="parameters">
<?php foreach ($part->parameters() as $parameter): ?>
<dt><?= $parameter->label() ?>:</dt>
<dd><?= $parameter->valueLabel() ?></dd>
<?php endforeach ?>
</dl>
</td>
</tr>
<?php endforeach ?>
</table>
<?php endforeach ?>
<?php endif ?>
<style>
.uniform__potty {
position: absolute;
left: -9999px;
}
</style>
In the resulting email, Uniform will by default print the raw data for each form field. This would mean that the Roomle configuration data is printed as a JSON string.
For a more user-friendly output, we need a custom email template in site/templates/emails/roomle-contact.php
:
<?= $message . "\n" ?>
<?php if ($configuration = $data['roomle-configuration']): ?>
-------------------
Configuration data:
<?= roomlePlan($configuration) ?>
<?php endif ?>
This email template is already referenced in the controller from step 1.
Warning: In this example we send a plain text email. It is strongly recommended to keep the setup like this. If you include a HTML email template, security attacks like cross-site scripting (XSS) are possible. This is because the configuration data is received from the client and can be manipulated by attackers. If you really need a HTML template, please ensure that you escape the output properly in custom snippets (see below).
Now you need to tell the Roomle plugin that it should submit the configuration data to your contact form whenever the "request product"/"request plan" button is clicked.
You can either do this by selecting the contact form page in the block settings or by setting a global default in site/config/config.php
:
<?php
return [
'lukasbestle.roomle' => [
'target' => 'contact'
]
];
The $plan
object and its children also have more fields and methods you can use for output on the form page (e.g. the part price). To see what is possible, please take a look at the plugin classes, particularly Configuration
, Parameter
, Part
and Plan
.
The email template from step 3 prints the whole $plan
object. Internally, this will render four snippets: roomle/plan.php
, roomle/configuration.php
, roomle/part.php
and roomle/parameter.php
.
If you want to customize the rendering in the email, you have two options:
- You can copy the default snippets from
site/plugins/roomle/src/config/snippets/roomle
tosite/snippets/roomle
and customize them. - You can modify the email template from step 3 directly (similar to the form page template from step 2).
With either of these solutions, you can also generate an HTML email as you have direct access to the individual fields of the configuration and can escape their values for HTML output.