Contact form not doing anything

Hi,
I’m totally new to forms and used to work with some Wordpress plugins in the past which made it really simple. I’ve tried using the following cookbook tutorial to create a very simple contact form: Email contact form | Kirby CMS

The form I eventually want to build is a bit more complicated that this one but just as a test I started with this one. Unfortunately I can’t get it to work.

I have a snippet (site/snippets/components/form.php) that gets loaded on the homepage containing:

<?php $success = ''; ?>
<main class="main">
    <h1><?= $page->title()->html() ?></h1>

    <?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="url" id="website" name="website" tabindex="-1">
        </div>
        <div class="field">
            <label for="name">
                Name <abbr title="required">*</abbr>
            </label>
            <input type="text" id="name" name="name" value="<?= esc($data['name'] ?? '', 'attr') ?>" required>
            <?= isset($alert['name']) ? '<span class="alert error">' . esc($alert['name']) . '</span>' : '' ?>
        </div>
        <div class="field">
            <label for="email">
                Email <abbr title="required">*</abbr>
            </label>
            <input type="email" id="email" name="email" value="<?= esc($data['email'] ?? '', 'attr') ?>" required>
            <?= isset($alert['email']) ? '<span class="alert error">' . esc($alert['email']) . '</span>' : '' ?>
        </div>
        <div class="field">
            <label for="text">
                Text <abbr title="required">*</abbr>
            </label>
            <textarea id="text" name="text" required>
                <?= esc($data['text'] ?? '') ?>
            </textarea>
            <?= isset($alert['text']) ? '<span class="alert error">' . esc($alert['text']) . '</span>' : '' ?>
        </div>
        <input type="submit" name="submit" value="Submit">
    </form>
    <?php endif ?>
</main>

The part on the top (<?php $success = ''; ?>) is not in the cookbook but otherwise the page throws an error: Undefined variable $success

I created a controller in site/controllers/contact.php containing this:

<?php
return function($kirby, $pages, $page) {

    $alert = null;

    if($kirby->request()->is('POST') && get('submit')) {

        // check the honeypot
        if(empty(get('website')) === false) {
            go($page->url());
            exit;
        }

        $data = [
            'name'  => get('name'),
            'email' => get('email'),
            'text'  => get('text')
        ];

        $rules = [
            'name'  => ['required', 'minLength' => 3],
            'email' => ['required', 'email'],
            'text'  => ['required', 'minLength' => 3, 'maxLength' => 3000],
        ];

        $messages = [
            'name'  => 'Please enter a valid name',
            'email' => 'Please enter a valid email address',
            'text'  => 'Please enter a text between 3 and 3000 characters'
        ];

        // some of the data is invalid
        if($invalid = invalid($data, $rules, $messages)) {
            $alert = $invalid;

            // the data is fine, let's send the email
        } else {
            try {
                $kirby->email([
                    'template' => 'email',
                    'from'     => 'yourcontactform@yourcompany.com',
                    'replyTo'  => $data['email'],
                    'to'       => 'you@yourcompany.com',
                    'subject'  => esc($data['name']) . ' sent you a message from your contact form',
                    'data'     => [
                        'text'   => esc($data['text']),
                        'sender' => esc($data['name'])
                    ]
                ]);

            } catch (Exception $error) {
                if(option('debug')):
                    $alert['error'] = 'The form could not be sent: <strong>' . $error->getMessage() . '</strong>';
                else:
                    $alert['error'] = 'The form could not be sent!';
                endif;
            }

            // no exception occurred, let's send a success message
            if (empty($alert) === true) {
                $success = 'Your message has been sent, thank you. We will get back to you soon!';
                $data = [];
            }
        }
    }

    return [
        'alert'   => $alert,
        'data'    => $data ?? false,
        'success' => $success ?? false
    ];
};

And an e-mail template in site/templates/emails/email.php:

Hello,

<?= $text ?>

<?= $sender ?>

When I press the submit button, the only thing happening is a page refresh to the top. When I scroll down again the form is empty… nothing seemed to happen. What am I missing here?

When you hit submit, does the success or error message appear on the page above the form when it reloads?

Do you have Mailhog setup locally? That will allow you to intcerpt the email to more easily check the form while developing.

ahh just spotted what is going on here i think. your controller must match the template its contorlling. rename the controller contact.php to home.php and it should work. This is why <?php $success = ''; ?> was needed since that should have been passed through from the controller. That is why that line was missing in the cookbook guide.

Hi! I’m not using Mailhog yet because I’m not really sure how it works… I’ll look into it!

You were right about the controller name. I’ve changed it to home and removed the success variable with success. When I try to submit the form, the page still refreshes and doesn’t show an error or succes message…

So, to recap:

  • You included this form in your home.php template.
  • You created a controller called home.php in site/controllers.

Then when you fill in

  • an email address
  • a name
  • and leave the text field blank

and then submit, nothing happens but a page reload. While you should get an error message for the missing text.

Yes I have a form snippet that is being loaded on home.php and created a controller named home.php as well with the exact content from the cookbook.

When I fill in an e-mail and a name without the textfield I get a standard tooltip that field is required. Since the controller is checking for a minimum of 3 characters I try to only add 1. When pressing submit, the page refreshes (back to the top) and when I scroll down to the form there is no error or succeed message.

Hm, looks as if it doesn’t go into the if statement.

Please add a

dump($_POST);

after if($kirby->request()->is('POST') && get('submit')) {

And try the same as before again. Does this output anything?

Then try again, this time removing the && get('submit') part from the if statement

The same thing continues to happen in both cases; refresh to top of page and when scrolling down an empty form without message

Is the project available somewhere on GitHub?

I know for sure that the code in the recipe works (tested it probably a hundred times by now), so there must be something specific to your project/code/configuration.

Not on GitHub but I created a simplified version: WeTransfer - Send Large Files & Share Photos Online - Up to 2GB Free

Did you test this simplified version on your own server? Works perfectly for me.

Yes tested it on localhost and it isn’t working. Uploaded it to a webserver and you’re right it’s working… Is there a way to test it on localhost? I know email testing needs something like MailHog but all the rest should work right?

Works fine locally using mailhog…

I have MailHog installed and can access the interface on: http://localhost:8025/

  • I added the following code to my config file:
  'email' => [
    'transport' => [
      'type' => 'smtp',
      'host' => 'localhost',
      'port' => 1025,
      'security' => false
    ]
  ],
  • This is in my controller where “MY EMAIL HERE” is my own e-mail address:
$kirby->email([
    'template' => 'email',
    'from'     => 'MY EMAIL HERE',
    'replyTo'  => $data['email'],
    'to'       => 'MY EMAIL HERE',
    'subject'  => 'New message from '. esc($data['name']),
    'data'     => [
        'name' => esc($data['name']),
        'email' => esc($data['email']),
    ])

But still only the page refreshes and the form is empty again. I know this has nothing to do with Kirby anymore since it is working on a production server but would appreciate any help!:slight_smile:

Leaving the mail side apart and intentionally adding an error in the form that is not caught already by the browser, we should still see the validation on the server side kicking in, and that doesn’t seem to happen.

Maybe tell us a bit more about your local dev environment…

Running an apache server with php 8.1.0 on the latest version of MAMP. Are there other specific things that I could share about the setup?

Perhaps it helps to turn debug mode on? Also, the server probably produces an error log file that might give you (and us) a hint.

Well, I’m a bit at my wit’s end. I tested your formtest example using Laravel Herd, MAMP Pro and the built-in server spun up with http://localhost:8000 and all of these bring up the error validation message without issues.

I understand:) thank you for checking and helping. It’s probably something with my local server but I will do the form testing on a production server than.

That is my problem right now and I have no idea why. On all my other website projects the contact forms are working, local and online. But this one does not. At some point I copied the whole tutorial code, changed nothing, but no success or failure messages appears. The dump() function only runs before the if statement.

What do I could miss here?