Forms in Kirby Blocks

Hi there,

I could use a little help… I´m trying to build a “contactform” block.

My problem is, that I get the error Block error: "Cannot use object of type Kirby\Cms\Block as array" in block type: "contactform". I think the error is thrown, because I try to access $data[‘somevalue’] in the template. I guess I have to pass $data to the block somehow.

As far as I know it is not possible to create controllers for blocks, right? Where to put the controller code?

Thanks :slight_smile:

1 Like

Block is an object, not an array. What is $data?

<?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" tabindex="-1">
    </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 ?>

This is my contactform.php (block template). The code was copied over from the cookbook example (https://getkirby.com/docs/cookbook/forms/basic-contact-form#the-contact-page)

$data is the kirby block object. Here’s the top part of a var_dump:
Bildschirmfoto 2021-01-04 um 10.39.16

Thank you!

As mentioned, Block is an object and cannot be accessed using array syntax… $data['text']

So it should be $block->text(). Since you are creating a new block, I’d use the $block variable, anyway.

@pixelijn: I´m not trying to access a field. I’m trying to access form-data passed from the controller.

Ah now I get it. The form example from the cookbook passes $data from the controller containing all the from-data. Inside of blocks $data referes to the current block instance.

So I changed $data to $fromdata and the error is gone.

But I’m still not sure where to put the controller code for my block as there are no block controllers, only page controllers, right?

Thank you for your help!

Exactly. But I guess the logic could go into the block snippet.

Very well, Ill try this then…

Thank you!

Hi - did you get this working? If you could share the snippet of your contact form block that would be awesome, I am currently implementing the same thing

Hi Mike,

yes is working… I pasted the controller-code from the example (see above) into page-contollers. The code is run only if a form is submitted:

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

Ok, I am stuck at this and still lacking some understanding…
I have gote a template contenu.php that uses a snippet cours.php (as listed page’s children), in that child there are blocks event.php with a contact form that triger a modal window to fill a contact form, the content of the contact form is a snippet registration-form.php
I put the copied code from cookbook in the controllers folder as registration-form.php then I got a Block error: “Undefined variable $success” in “event”.
I try to copy the controller code into the block event.php, but none of the registration-form fields appear…
Can you help with this one? Thank you :slightly_smiling_face:

What does that look like now. And maybe also post the contenu.php template for a better understanding of the structure.

not any good yet… thank you for the help (once again)

<div class="small margin-s">
<a href="<?= $page->parent()->url() ?>"><?= $page->parent()->title()?>/</a>
</div>
<div class="grid" style="--gutter: 1.5rem">
<section class="column text" style="--columns: 8">
<?php snippet('introduction') ?>
<?php if ($page->children()->isNotEmpty()) : ?>
<?php snippet('cours') ?>
<?php endif ?>
<?php foreach ($page->contenu()->toBlocks() as $block): ?>
<?= $block ?>
<?php endforeach ?>
</section>
</div>

this the cours snippet

<?php foreach($page->children()->listed() as $cours): ?>
<h2><?= h($cours->title(), true) ?></h2>
<h3><?= h($cours->subtitle(), true) ?></h3>
<?= h($cours->presentation()->kt(), true) ?>
<div class="events">
<?php foreach ($cours->cours()->toBlocks() as $block): ?>
<?= $block ?>
<?php endforeach ?>
 </div>
<?php endforeach ?>

and the form in a block call event.php

<a href="#popup"><button align="center"><?= $data->email() ?></button></a>
    <div id="popup" class='modal' role="dialog">
        <div class="modal-content">
        	<div class="header">
    				 <a href="#" id="close">
    					 <div class="box box3">
    					  <svg viewbox="0 0 40 40"><path class="close-x" d="M 10,10 L 30,30 M 30,10 L 10,30" /></svg>
    					</div>
    				</a>
    				<h2>Inscription: <?= $data->intitule()->kt() ?></h2>
    			</div>
    			<div class="copy">
            <?php snippet('registration-form') ?>
          </div>
    </div>
    <a href="#"><div class="overlay"></div></a>
    </div>

And where is the form handling logic now? Did you put the complete controller into the registration-form snippet?

no i put it back in the controllers folder, should I put it in the snippet? I try that but it did not work, empty fields in the form

A controller always belongs to a template, so it doesn’t make any sense to name that controller register-form.php, because that template does not exist. You would need a controller for contenu.php, because that is the only template involved here.

2 Likes

oh, as always when you say it, it makes so much sense. thank you very so much! it seems to work :smiley:. good evening @texnixe

1 Like

Hi Puppet9.

I’m afraid I couldn’t follow your instructions. Would it be possible to explain the adjustments that are necessary in comparison to the instructions at Email contact form | Kirby CMS? Unfortunately, I still get the error message „Cannot use object of type Kirby\Cms\Block as array" in block type: …“.

Thank you for your help!

Just had the same problem. The issue is that the $data variable is already used by Kirby block logic, so you need to rename the variable that is passed from the controller—otherwise the code in the template is trying to access the wrong $data variable which causes said error.