Best place to put phpmailer files

Hello, I’m going to add a contact form to my kirby site, it works well with a simple html form + some php in controller (followin the bastian example on gist) Now I want to use phpmailer ton avoid spam, but I was wondering what is the best place phpmailer files.

This question is global, when I want to load external assets, I don’t know what is the best folder to place them. A controller ? In assets directory ? It will be great if the php files can have the benefits of kirby variables and chaining.

I am not sure I understand your question 100%, but if you want to add forms to your website I would have a look at @mzur 's uniform plugin.

You can put those files anywhere you want, but the easiest way would be as a plugin, I guess, if need be, you can write a simple wrapper.

Check out this post as well: Send emails using PHPMailer

OK, So, after long days, numerous tries and copypasta scripts mixing (yeah, I’m not a developper) I think I have achevied to make a little contact form with spam honypot and send mails trough phpmailer with an email wrapper in a plugin (thaks to other posts find here and there).

It works, but I can’t figure some details.

  • If I left a field blank or the email is invalid, kirby throw a php error and “kills” the page. The error seems to come from kirby email sending function kirby/vendor/getkirby/toolkit/lib/email.php and not from phpmailer. How can I make phpmailer handle errors and display it ? Why kirby overtakes ?
  • Related to the question above: who check mail validity and when ? Kirby seems to check it in very first, avoiding further controls.
  • For the moment the code that sends mails is in the page controller, how I can generalize cleanly it if I want it in other pages without recopying the code ? Put it in the form snippet ? In another plugin ?
  • If I want to add other phpmailer features such as SMTP or language in the future (for the moment I have just one phpmailer basic file) How can I achieve it ? By calling other files (or autoloader) at the start of my driver ?
  • General question: is the plugin use is a good idea ? Really I can’t figure how all of this works and I don’t even know by what magix the plugin enters in game. Where is it called ? Is this automatic ?

Sorry for those questions, but I try to understand what I did and if I did it clean.

Here is my code:

contact form snippet:

<form id="contact" method="post" action="#contact">
        <p>Vous pouvez me contacter par mail à l'adresse <a href="mailto:<?php echo page('about')->email(); ?>"><?php echo page('about')->email(); ?></a>      ou directement via le formulaire ci-dessous</p>
        <?php if($alert): ?>
        <p class="alert">
          <?php echo html($alert) ?> </p>
        <?php endif ?>
          <label for="name">Votre nom :</label>
          <input name="name" type="text" id="name" <?php if (isset($_POST['name'])) echo 'value="'.$_POST['name'].'"';?>/>
          <label for="email">Votre email :</label>
          <input name="email" type="text" id="email" <?php if (isset($_POST['email'])) echo 'value="'.$_POST['email'].'"';?> />
          <label for="message">Votre message :</label>
          <textarea name="message" id="message"><?php if (isset($_POST['message'])) echo $_POST['message'];?></textarea>
        <!-- The following field is for robots only, invisible to humans: -->
        <p aria-hidden=”true” class="visually-hidden" id="pot">
          <label for="robotest">Si vous n'êtes pas un robot spammeur, laissez le champ suivant vide :</label>
          <input name="robotest" type="text" id="robotest" class="robotest" />
          <input type="submit" value="Envoyer" class="submit" />

about page (where the form is) controller:

return function($site, $pages, $page) {
  $alert = null;
//Si post contient quelque chose
if(!empty($_POST) ){
    //on remplit les variables avec le contenu du form
    $to = page('about')->email();
    $subject = 'Message de '.$_POST['name'].' via le formulaire de contact de';
    $from = $_POST['name'].' '.$_POST['email'];
    $message = $_POST['message'];
    $robotest = $_POST['robotest'];

      $alert = "Quelque chose ne s'est pas passé comme prévu.";
        } else {
        $email = new Email(array(
            'to'      => $to,
            'from'    => $from,
            'subject' => $subject,
            'body'    => $message,
            'service' => 'phpmailer'
        if ($email->send()) {
          $alert = "Votre message a bien été envoyé, j'y répondrai dès que possible !";
          } else {
              $alert = $email->error()->message();
  return compact('alert');

phpmailer-driver.php (in site/plugins/phpmailer-driver, same folder as class.phpmailer.php)

email::$services['phpmailer'] = function($email) {
	require_once(__DIR__ . DS . 'class.phpmailer.php');
	$mail = new PHPMailer;


	if ($email->attachment != null) {

	$mail->Subject = $email->subject;
	$mail->Body = $email->body;

	if (!$mail->send()) {
		throw new Error('PHPMailer error: ' . $mail->ErrorInfo);