Contact form “Undefined variable: success”

So, I’m trying to implement a contact form according to Contact form | Kirby CMS but when I’m loading the page I’m getting:

Whoops\Exception\ErrorException thrown with message “Undefined variable: success”

Stacktrace:
#16 Whoops\Exception\ErrorException in ~/site/snippets/section-contact.php:4
#15 Whoops\Run:handleError in ~/site/snippets/section-contact.php:4
#14 include in ~/kirby/src/Toolkit/F.php:403
#13 Kirby\Toolkit\F:loadIsolated in ~/kirby/src/Toolkit/F.php:380
#12 Kirby\Toolkit\F:load in ~/kirby/src/Toolkit/Tpl.php:35
#11 Kirby\Toolkit\Tpl:load in ~/kirby/config/components.php:288
#10 Kirby\Cms\App:{closure} in ~/kirby/src/Cms/App.php:1390
#9 Kirby\Cms\App:snippet in ~/kirby/config/helpers.php:674
#8 snippet in ~/site/templates/home.php:4
#7 include in ~/kirby/src/Toolkit/F.php:403
#6 Kirby\Toolkit\F:loadIsolated in ~/kirby/src/Toolkit/F.php:380
#5 Kirby\Toolkit\F:load in ~/kirby/src/Toolkit/Tpl.php:35
#4 Kirby\Toolkit\Tpl:load in ~/kirby/src/Cms/Template.php:167
#3 Kirby\Cms\Template:render in ~/kirby/src/Cms/Page.php:1172
#2 Kirby\Cms\Page:render in ~/kirby/src/Cms/App.php:686
#1 Kirby\Cms\App:io in ~/kirby/src/Cms/App.php:1039
#0 Kirby\Cms\App:render in ~/index.php:5

The contact page type in the content directory is called contact.txt, the controller is in /site/controllers/contact.php, the site is actually a one-pager website where the contact template is loaded via a snippet called section-contact.php within home.php.

Does this have something to do with the file names, that the controller is not properly mapped?

If it is a one-pages and the home.php template is the template that outputs the page, then using the contact.php controller will never be called. Put the logic into the home controller.

Ah, thanks, I thought it must be something like that. Renaming the controller file to home.php solved this problem. Now I just don’t understand why I get the error

The form could not be sent: Undefined variable: text

when sending the form? I don’t have any variable like that declared anywhere. This is the form part of the template snippet:

<?php if($success): ?>
<div class="alert success">
		<p><?= $success ?></p>
</div>
<?php else: ?>
<?php if (isset($alert['error'])): ?>
		<div class="error"><?= $alert['error'] ?></div>
<?php endif ?>
<form method="post" action="<?= $page->url() ?>">
	<div class="website">
		<label for="k_website">Website <abbr title="required">*</abbr></label>
		<input type="website" id="k_website" name="k_website" tabindex="-1">
	</div>
	<div>
		<label for="k_name">Name <small>(optional)</small></label>
		<input type="text" id="k_name" name="k_name" value="<?= $form_data['name'] ?? '' ?>">
		<?= isset($alert['name']) ? '<span class="alert error">' . html($alert['name']) . '</span>' : '' ?>
	</div>
	<div>
		<label for="k_email">E-Mail</label>
		<input type="email" id="k_email" name="k_email" value="<?= $form_data['email'] ?? '' ?>" required>
		<?= isset($alert['email']) ? '<span class="alert error">' . html($alert['email']) . '</span>' : '' ?>
	</div>
	<div>
		<label for="k_betreff">Betreff <small>(optional)</small></label>
		<input type="text" id="k_betreff" name="k_betreff" value="<?= $form_data['subject']?? '' ?>">
		<?= isset($alert['subject']) ? '<span class="alert error">' . html($alert['subject']) . '</span>' : '' ?>
	</div>
	<div>
		<label for="k_nachricht">Nachricht</label>
		<textarea id="k_nachricht" name="k_nachricht" required><?= $form_data['message']?? '' ?></textarea>
		<?= isset($alert['message']) ? '<span class="alert error">' . html($alert['message']) . '</span>' : '' ?>
	</div>
	<input type="submit" name="k_submit" value="Absenden">
</form>
<?php endif ?>

and this is the controller:

<?php
return function($kirby, $pages, $page) {
	$alert = null;
	if($kirby->request()->is('POST') && get('k_submit')) {

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

			$form_data = [
					'name'  => get('k_name'),
					'email' => get('k_email'),
					'subject'  => get('k_betreff'),
					'message'  => get('k_nachricht')
			];

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

			$messages = [
					'email' => 'Bitte geben sie eine gültige E-Mail-Adresse ein',
					'message'  => 'Der Text muss mindestens drei und darf höchstens 3000 Zeichen lang sein'
			];

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

					// the data is fine, let's send the email
			} else {
					try {
							$kirby->email([
									'template' => 'email',
									'from'     => 'test@example.com',
									'replyTo'  => $form_data['email'],
									'to'       => 'test@example.com',
									'subject'  => empty($form_data['subject']) ? 'Nachricht über das Kontaktformular' : esc($form_data['subject']),
									'data'     => [
											'subject'   => esc($form_data['subject']),
											'message'   => esc($form_data['message']),
											'sender' => esc($form_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 = 'Vielen Dank, die Nachricht wurde gesendet. Wir werden uns so bald wie möglich bei ihnen melden.';
							$form_data = [];
					}
			}
	}

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

Anyone see what the problem could be?

Nevermind, it was a wrong variable in the email template itself, nothing in the form or the controller. Problem solved.