Forms with attachments
This recipe extends the basic contact form example, but this time the user can attach some files. As an example we use a job application form.
To follow this example, your content structure should look like this:
We also need the following files:
- an applications template with the form snippet
- the application form snippet
- the controller that handles the form logic
- a plain text or an HTML email template
- two templates for the
jobs
overview page and its subpages (see the demo download below)
The workflow is like this:
When users visit a job page, they can click on a link that leads to the application form. The link contains the reference that is then prefilled in the form's reference field. Users can however change this field input if they decide they would rather apply for another job (or if they visit the applications
page directly).
With this setup, we keep the application process away from the job listings and can put it behind a login wall if needed. Instead of handling the applications on a general applications form like in this example, you could also show the form on every job page.
The job application page
Create an applications
page with an applications.txt
content file. For our means, we only need the title in the content file, the rest is up to you.
For use in the Panel, you can create a blueprint for the page. We will skip this step here.
The applications.php
template
The template contains the form and will display error messages if something goes wrong. To keep the applications.php
template clean, we include the form as a snippet.
The form snippet
The form snippet contains some form fields (name
, email
, reference
, message
, file
) and a honeypot field to ensure a minimum level of spam bot protection.
The honeypot field needs to be positioned off the screen via CSS. Therefore add these styles to your stylesheet (you can change the class and styling).
Note that since we want to upload files, we have to set the encoding type attribute to enctype="multipart/form-data"
.
Because the $data
and $alert
variables get controlled by user input, it is important to escape the text to protect against XSS vulnerabilities.
The controller
The controller handles our form validation logic.
Let's go through the most important steps here in detail. The rest is commented in the code snippet.
Validate input data
In our controller, the form evaluation starts once we receive a POST
request. First, we check if a bot got trapped in our honeypot. In this case, we send him back to the page and stop script execution.
Next, we check if all form fields have been filled in according to our validation rules using the invalid()
helper:
- All fields are required and must be filled out.
- The
email
field must contain a valid email address. - The
name
field must be at least 3 characters long. - The
message
field must be between 10 and 3000 characters. - The
reference
field must be a valid reference from one of thejobs
subpages
You can change these rules depending on the type of data you want to obtain and use Kirby's validators or your own custom validators to make sure you get the desired data.
Validate uploaded files
We then handle the file submissions. We fetch the uploaded file(s) with $kirby->request()->files()->get('file')
, where file
is the name of our input field. If the user tries to upload more than 3 files, we add a message to the $alerts
array.
Then we loop through the files array and check for each upload if it is valid:
- We check the
$upload['error']
value to make sure that we have at least one upload and no other error occurred - We check the file size to make sure that the file is not larger than allowed
- We check if the uploaded is a PDF
As the last step in this loop we rename the temporary upload name to a sanitized version of the original file name.
Send email
If all went well, we try to send the email together with the file attachments in a try - catch
block.
If the email was sent, we store the user's name and the job reference number in the session and redirect the user to the success
page.
The email templates
In our $kirby->email()
method above, we defined a template we want to use to send the email. In this example, we use a template called email
, which is stored in /site/templates/emails
.
We can use both a plain text template and/or an HTML version. You can read more about this in the email guide.
Here are the two email templates:
The plain text template
The plain text template gets the extension .php
.
The HTML template
The HTML template gets the extension html.php
.
Both templates are kept very simple. Kirby provides the variables we defined in the data
array ready to be used in the email templates as $text
and $sender
. You can of course change them to your liking.
The success page
The success content file contains placeholders for the applicant's name and the job reference number:
A plugin to replace the placeholders
In the plugin, we replace the name and event placeholders in the text with the data we stored in the session.
Download the demo
For a working example, download the demo "Jobkit".
Extending the example
You can of course extend this example:
- Progressively enhance with JavaScript validation.
- Integrate other field types.
- …