Simple Email Contact Form

Is there a simple solution or guide to create a contact me email form in Kirby 3?

There is an older version for Kirby 2, with the help of the email documentation, you should be able to adapt that.

Here are the gists for Kirby 2

In the controller, you have to change lines 34 to 53 and use the new email engine instead. The rest should be basically the same.

I’ve put it on the up next list for the cookbook.

Thank you @texnixe

Just to confirm, am I changing this:

  // create the body from a simple snippet
      $body  = snippet('contactmail', $data, true);
      // build the email
      $email = email(array(
        'to'      => 'bastian@getkirby.com',
        'from'    => 'contactform@getkirby.com',
        'subject' => 'New contact request',
        'replyTo' => $data['email'],
        'body'    => $body
      ));
      // try to send it and redirect to the
      // thank you page if it worked
      if($email->send()) {
        go('contact/thank-you');
      // add the error to the alert list if it failed
      } else {
        $alert = array($email->error());
      }

to this:

try {
  $kirby->email([
    'from' => 'welcome@supercompany.com',
    'replyTo' => 'no-reply@supercompany.com',
    'to' => 'someone@gmail.com',
    'cc' => 'anotherone@gmail.com',
    'bcc' => 'secret@gmail.com',
    'subject' => 'Welcome!',
    'body'=> 'It\'s great to have you with us',
  ]);
} catch (Exception $error) {
  echo $error;
}

But with my own email obviously :slight_smile:

Yep, and in the controller return function with the $kirby variable:

return function($kirby) {

You can also check out the fork by https://gist.github.com/starckio/30d800a6518ca4c966f48bfb9f658962 which has some useful enhancements, like storing the value in case an error appears so that the form is not emptied all the time and a little honeypot.

A working example is now in review in case you are still struggling: https://github.com/getkirby/getkirby.com/pull/423/files

I set this up but after filling in the details all I get is *The form could not be sent * :frowning:

Hm, did you set up the email templates both for HTML and plain text? Since its failing in the try-catch block, there seems to be something wrong in the email setup.

Same issue here.
If I have email.text.php and email.html.php the form can’t be sent. I need to have a email.php and it works fine.

Great Stuff, but unfortunately I can’t integrate the form into my Onepager. The home.php does not work with the controller.

What can I do?

Thanks

@ingman What are you referring to? The cookbook example?

In case of a one pager that uses the home.php template, you have to put the logic into a /site/controllers/home.php controller.

1 Like

Thanks for the quick feedback.

Yes, I use the cookbook example and yes, I put the logic into the controllers/home.php controller, but it doesn’t work. When you click on “send”, only the page is reloaded.

It works fine if I use a contact.php instead of home.php.

Have I forgotten something?

Could you please post the complete snippet that contains the contact form? It should also work on the homepage.

For testing I renamed the contact.php to home.php. The controller is the same as in my example only, it is called home.php and contains my email addresses.

The code of my home.php:

<?php snippet('header') ?>

<main class="main">
  <?php if($success): ?>
    <div class="alert success">
      <p><?= $success ?></p>
    </div>
  <?php else: ?>
  <?php if (isset($alert['error'])): ?>
    <div><?= $alert['error'] ?></div>
  <?php endif ?>
  <form method="post" action="<?= $page->url() ?>">
    <div class="honeypot">
      <label for="website">Website <abbr title="required">*</abbr></label>
      <input type="website" id="website" name="website">
    </div>
    <div class="field">
      <label for="name">Name <abbr title="required">*</abbr></label>
      <input type="text" id="name" name="name" value="<?= $data['name'] ?? '' ?>" required>
      <?= isset($alert['name']) ? '<span class="alert error">' . html($alert['name']) . '</span>' : '' ?>
    </div>
    <div class="field">
      <label for="email">Email <abbr title="required">*</abbr></label>
      <input type="email" id="email" name="email" value="<?= $data['email'] ?? '' ?>" required>
      <?= isset($alert['email']) ? '<span class="alert error">' . html($alert['email']) . '</span>' : '' ?>
    </div>
    <div class="field">
      <label for="text">Text <abbr title="required">*</abbr></label>
      <textarea id="text" name="text" required><?= $data['text']?? '' ?></textarea>
      <?= isset($alert['text']) ? '<span class="alert error">' . html($alert['text']) . '</span>' : '' ?>
    </div>
    <input type="submit" name="submit" value="Submit">
  </form>
  <?php endif ?>
</main>

<?php snippet('footer') ?>

Hm, are you using the latest Kirby release (3.2)?

I don’t really see how this can’t work, and it works when I use the code in a fresh Starterkit on the home page.

Yes, I use 3.2.

I’ll experiment with a fresh starter kit and try to find out by exclusion procedure.

Thanks so far

So, some very smart guys have the solution and it’s really very simple. You just have to make “slash” behind the form action like this: <form action="<?php echo $page->url()?>/" method="post">

This is how the email form also works with home.php

Here is the github link for the solution:

Thanks to mzur

Hi there,

I hope you don’t mind me reopening that thread, since none of the proposed solutions solves the problem I got. Neither suggestions from this thread nor from https://github.com/mzur/kirby-uniform/issues/22 are working.

With respect to KIRBY, I’m quite a newbie, so I might get something fundamentally wrong.

I’ve been integrating an email form according to the cookbook recipe (sorry, forum doesn’t permit me to include the link, only 2 allows), but placed the main code inside a snippet instead of a template.

The template doesn’t have much more than a mere

<?php snippet('header') ?>
   <main class="main" role="main">
      <?php snippet('section-contactform') ?>
   </main>
<?php snippet('footer') ?>

For testing purposes, the site is included on the bottom of the main page and as a separate page. I got the controller code (identical) in both contactform.php and home.php.

For what I can see, there’s an exception in the try-catch block of the controller code, but don’t get an idea what’s happening here from the trace:

#0 /var/www/sites/v3.markusschatzl.de/kirby/src/Cms/Email.php(53): Kirby\Cms\Email->template() 
#1 /var/www/sites/v3.markusschatzl.de/kirby/src/Cms/App.php(466): Kirby\Cms\Email->__construct(Array, Array) 
#2 /var/www/sites/v3.markusschatzl.de/site/controllers/home.php(45): Kirby\Cms\App->email(Array) 
#3 [internal function]: Kirby\Cms\App->{closure}(Object(Kirby\Cms\App), Object(Kirby\Cms\Pages), Object(Kirby\Cms\Page)) 
#4 /var/www/sites/v3.markusschatzl.de/kirby/src/Toolkit/Controller.php(49): Closure->call(Object(Kirby\Cms\App), Object(Kirby\Cms\App), Object(Kirby\Cms\Pages), Object(Kirby\Cms\Page)) 
#5 /var/www/sites/v3.markusschatzl.de/kirby/src/Cms/App.php(367): Kirby\Toolkit\Controller->call(Object(Kirby\Cms\App), Array) 
#6 /var/www/sites/v3.markusschatzl.de/kirby/src/Cms/Page.php(345): Kirby\Cms\App->controller('home', Array, 'html') 
#7 /var/www/sites/v3.markusschatzl.de/kirby/src/Cms/Page.php(1115): Kirby\Cms\Page->controller(Array, 'html') 
#8 /var/www/sites/v3.markusschatzl.de/kirby/src/Cms/App.php(584): Kirby\Cms\Page->render() 
#9 /var/www/sites/v3.markusschatzl.de/kirby/src/Cms/App.php(870): Kirby\Cms\App->io(Object(Kirby\Cms\Page)) 
#10 /var/www/sites/v3.markusschatzl.de/index.php(5): Kirby\Cms\App->render() 
#11 {main}

The site is a test setup and already running http://v3.markusschatzl.de

If any of you could provide a hint where to proceed, I’d be very happy.

Thank you,
Markus

Do the email templates exist?

They do, both email.php and email.html.php. But you make a point: I called the directory in site/templates/ “email” instead of “emails”.

It still doesn’t work smoothly though, it seems to raise an issue with PHPMailer now (all form Input data was correct and usable):

#0 /var/www/sites/v3.markusschatzl.de/kirby/vendor/phpmailer/phpmailer/src/PHPMailer.php(1518): PHPMailer\PHPMailer\PHPMailer->mailSend('Date: Thu, 24 O...', 'This is a multi...') 
#1 /var/www/sites/v3.markusschatzl.de/kirby/vendor/phpmailer/phpmailer/src/PHPMailer.php(1352): PHPMailer\PHPMailer\PHPMailer->postSend() 
#2 /var/www/sites/v3.markusschatzl.de/kirby/src/Email/PHPMailer.php(74): PHPMailer\PHPMailer\PHPMailer->send() 
#3 /var/www/sites/v3.markusschatzl.de/kirby/src/Email/Email.php(40): Kirby\Email\PHPMailer->send()
#4 /var/www/sites/v3.markusschatzl.de/kirby/src/Cms/App.php(466): Kirby\Email\Email->__construct(Array, false) 
#5 /var/www/sites/v3.markusschatzl.de/site/controllers/home.php(45): Kirby\Cms\App->email(Array) #6 [internal function]: Kirby\Cms\App->{closure}(Object(Kirby\Cms\App), Object(Kirby\Cms\Pages), Object(Kirby\Cms\Page)) 
#7 /var/www/sites/v3.markusschatzl.de/kirby/src/Toolkit/Controller.php(49): Closure->call(Object(Kirby\Cms\App), Object(Kirby\Cms\App), Object(Kirby\Cms\Pages), Object(Kirby\Cms\Page)) 
#8 /var/www/sites/v3.markusschatzl.de/kirby/src/Cms/App.php(367): Kirby\Toolkit\Controller->call(Object(Kirby\Cms\App), Array) 
#9 /var/www/sites/v3.markusschatzl.de/kirby/src/Cms/Page.php(345): Kirby\Cms\App->controller('home', Array, 'html') 
#10 /var/www/sites/v3.markusschatzl.de/kirby/src/Cms/Page.php(1115): Kirby\Cms\Page->controller(Array, 'html') 
#11 /var/www/sites/v3.markusschatzl.de/kirby/src/Cms/App.php(584): Kirby\Cms\Page->render() 
#12 /var/www/sites/v3.markusschatzl.de/kirby/src/Cms/App.php(870): Kirby\Cms\App->io(Object(Kirby\Cms\Page)) 
#13 /var/www/sites/v3.markusschatzl.de/index.php(5): Kirby\Cms\App->render() 
#14 {main}

How are you trying to send the mail? Via a provider?