Kirby-tag value - conceptual problem

hi there…
i want to implement a link that opens a modal with ajax-based contact-form with custom recipient.
so my idea was to make a kirby-tag, that injects a snippet into frontend with the complete form… the ajax calls php-script (POST) to send mail and get status of sending…

both snippets are tested with hardcoded recipient in the second php-script… so the code works.

Well… my idea was to make a kirby-tag like (mailform: to set recipient directly when using this tag.
(have to use it on my website in several places with several recipients)

Since i don’t want to reveal the mailadress to visitor, i’m lost…

As far, as i know, a kirby-tag-plugin works like “sending value to code”… everything is handled there… and result is returned.
This works for generating the “modal + link (button)” in frontend, but how to send value to second php-script without revealing the mailadress to the first-one?

i hope my thoughts are clear enough… please ask if it’s not clear enough =)

You can store that value in the session for the other script to pick up.

hey… thx for reply…
as far as i understand it correctly, the concept of sessions do need visitor accept cookies, correct?
that’s not an option.

Then you have to send your data with your post request, and if you don’t want to reveal it, you would have to encode it and then decode again.

hmm… what about…
counting all used same type kirbytags on the page… iterate over them to find the number with the correct value… this number could then be send over to be used in the final php script.
there could be another counting of all used kirbytags on that page to parse the one of given number.

For example on one page, my custom kirbytag is used 7 times… like:
(exaggerated example… not a real usecase)

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy 
eirmod tempor invidunt ut labore et dolore magna (mailform: text: aliquyam erat), 
sed diam voluptua. At vero eos et accusam 
(image: foobar.jpg) 
et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea
takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, 
(mailform: button: true)
consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt
ut labore et dolore magna aliquyam (mailform: image: blah.jpg)
lorem ipsum (mailform: text: group2) ipsum lorem
dolor (mailform: (mailform:

regex magic finds the mailform tag is used 7 times… now iterate over it to get tag-no. with used mailadress. for example, which is no. 6.

now, the final php, which is called from the ajax, could also count all used kirbytags in that page and greps the mailadress of no. 6.

i see, it’s complicated… but as far as i understand, there is no need of cookies… no need of encryption of data… mailadress is not revealed plain nor encrypted.

i guess, there is nothing build in to count/filter kirbytags of a page?

That somehow sounds unnecessarily complicated. How many possible email addresses will there possibly be in a site?

on the whole site… dozens.
on a single page… mostly only one… but it could be that there will be more than one.

Hm, maybe you can store these email addresses in site in a structure field with a reference code (like a lookup table), then in the tag, instead of the email address, you use this reference. In your script, you look up the email address for this reference.

that idea of a “simple database” also came into my mind… but makes it more complicated on usage.

i’m openminded for new ideas =)
but those ideas should 1. be simple in usage 2. protecting data

i was implementing a working solution via kirbybuilder-block. but those blocks have unique IDs to search for and find data… kirbytags don’t

I think with the new blocks editor, something like this would be easy to implement.

In a textarea field, the ideal way would be a custom toolbar icon to insert the mailform tag with a select field in a dialog to select the mail address from a structure field of options. This field would insert the reference by which you could then easily look up the email address.

But even if users had to insert the reference manually, it wouldn’t be that bad.

na… that’s not what i want to have as a final usage… the given mailadresses are unknown and should not be added to a list before usage.

thats the same idea as before with a “simple database” that have to be curated.

Well, if you don’t like it, fair enough. I don’t have any better ideas.

thx anyway! you are still a great help… brainstorming brings new ideas to my mind =)

the idea of sending enrypted mailadress to the script is top notch and in my top-list of ideas to the problem =)

are there any helpers in kirby to grep for kirbytags?

Nope, but you can find them with a regex pattern. There is an example somewhere here

Kirby 2 but might help: Just parse kirbytags

In your case, you would limit the regex to mailform tags.

thx a very lot! i also just laughed… because of searching for regex and kirbytags… i found this two years old post, where you helped me on a kribytag and regex =)

(p.s. i still don’t have any clue about regex)

That’s actually the one I was originally looking for… :grinning:

seems i got it…
i will paste the solution as a plugin, when it is finished.

A post was merged into an existing topic: Replace strings systemwide before rendering in the browser

ok… it’s a dirty solution… but it works =)
The Template-file in here is based on UIKit integrated in The Zero One Template

I just post this for others in need. i do not have the skills and time to maintain this as a plugin, nor is this universal (because of uikit dependence)

At first i made a solution without encryption like described above, (via iterating over used tags at first and third stage) but this was problematic in various cases… so i decided to go for a solution that is more compatible… for example in use via kirbytag()

Maybe this is a startingpoint for a new feature for the The Zero One Template @mrfreedom


Kirby::plugin('demlak/mailform', [
  'snippets' => [
    'mailformmodal' => __DIR__ . '/snippets/mailformmodal.php',
  'templates' => [
    'mailformparse' => __DIR__ . '/templates/mailformparse.php',
  'routes' => function () {
    return [
      'pattern' => 'mailformparse',
      'method'  => 'GET|POST',
      'action'  => function () {
        return Page::factory([
          'slug' => 'mailformparse',
          'template' => 'mailformparse',
          'content' => [
            // choose own 
            'decryption_iv' => '1234567891234567',
            // choose own
            'decryption_key' => 'mailform_by_demlak',
            'ciphering' => 'AES-128-CTR',
  'tags' => [
    'mailform' => [
      'attr' => [
        // image-tag currently not used in template
      'html' => function($tag) {
        // Store a string into the variable which need to be Encrypted 
        $simple_string = $tag->value(); 
        // Store the cipher method 
        $ciphering = "AES-128-CTR"; 
        // Use OpenSSl Encryption method 
        $iv_length = openssl_cipher_iv_length($ciphering); 
        $options = 0; 
        // Non-NULL Initialization Vector for encryption 
        $encryption_iv = '1234567891234567'; 
        // Store the encryption key 
        $encryption_key = 'mailform_by_demlak'; 
        // Use openssl_encrypt() function to encrypt the data 
        $encryption = openssl_encrypt($simple_string, $ciphering, $encryption_key, $options=0, $encryption_iv); 

        return snippet('mailformmodal', [
          'class' => $tag->attr('class'),
          'label' => $tag->attr('label'),
          'image' => $tag->attr('image'),
          'title' => $tag->attr('title'),
          'targetid' => $encryption,
          'randid' => Str::random(3)
          ], true


<a href="#modal-<?= $randid ?>" class="<?= $class ?>" uk-toggle><?= e(empty($label), "Kontakt", $label) ?></a>
<div id="modal-<?= $randid ?>" class="uk-flex-top" uk-modal>
    <div class="uk-modal-dialog uk-modal-body uk-margin-auto-vertical">
        <button class="uk-modal-close-default" type="button" uk-close></button>
        <h3 class="uk-text-break">
            <?php e(empty($title), $page->title()->html() . " - Kontakt", $title) ?>
        <hr />
        <div class="uk-text-right">
            <form id="my_form-<?= $randid ?>" onsubmit="submitForm<?= $randid ?>(); return false;">
                <div class="tm-hon">
                    <label for="website">Website <abbr title="required">*</abbr></label>
                    <input type="website" id="website" name="website">
                <p class="uk-inline uk-width-1-1">
                    <span class="uk-form-icon" uk-icon="icon: user"></span>
                    <input id="name<?= $randid ?>" placeholder="<?= $site->labelName()->html() ?>" required class="uk-input">

                <p class="uk-inline uk-width-1-1">
                    <span class="uk-form-icon" uk-icon="icon: mail"></span>
                    <input id="email<?= $randid ?>" placeholder="<?= $site->labelEmail()->html() ?>" type="email" required class="uk-input">
                <p class="uk-inline uk-width-1-1">
                    <textarea id="text<?= $randid ?>" placeholder="<?= $site->labelMessage()->html() ?>" rows="10" required class="uk-textarea"></textarea>
                    <span id="status_<?= $randid ?>"> </span>
                    <input id="mybtn<?= $randid ?>" type="submit" value="<?= $site->labelSubmit()->html() ?>" class="uk-button uk-button-default">

<script type="text/javascript">
        function _(id){ return document.getElementById(id); }
        function submitForm<?= $randid ?>(){
                _("mybtn<?= $randid ?>").disabled = true;
                _("status_<?= $randid ?>").innerHTML = 'please wait ...';
                var formdata = new FormData();
                formdata.append( "targetid", '<?= $targetid ?>');
                formdata.append( "name", _("name<?= $randid ?>").value );
                formdata.append( "email", _("email<?= $randid ?>").value );
                formdata.append( "text", _("text<?= $randid ?>").value );
                var ajax = new XMLHttpRequest();
       "POST", "<?= $site->url() ?>/mailformparse" );
                ajax.onreadystatechange = function() {
                        if(ajax.readyState == 4 && ajax.status == 200) {
                                if(ajax.responseText == "success"){
                                        _("my_form-<?= $randid ?>").innerHTML = '<h2>Danke '+_("name<?= $randid ?>").value+', <br>deine Nachricht ist gesendet.</h2>';
                                } else {
                                        _("status_<?= $randid ?>").innerHTML = ajax.responseText;
                                        _("mybtn<?= $randid ?>").disabled = false;
                ajax.send( formdata );


$alert = null;

if( isset($_POST['name']) && isset($_POST['email']) && isset($_POST['text']) ){

        $targetid = get('targetid');
        $ciphering = $page->ciphering();
        $decryption_key = $page->decryption_key();
        $decryption_iv = $page->decryption_iv();

        // Use openssl_decrypt() function to decrypt the data 
        $targetmail=openssl_decrypt($targetid, $ciphering, $decryption_key, $options=0, $decryption_iv); 

        // check the honeypot
        if(empty(get('website')) === false) {

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

        $rules = [
            'name'  => ['required', 'min' => 3],
            'email' => ['required', 'email'],
            'text'  => ['required', 'min' => 3, 'max' => 3000],

        $messages = [
            'name'  => esc($site->labelAlertName()->or('Please enter a valid name')),
            'email' => esc($site->labelAlertEmail()->or('Please enter a valid email address')),
            'text'  => esc($site->labelAlertMessage()->or('Please enter a text between 3 and 3000 characters'))

        // some of the data is invalid
        if($invalid = invalid($data, $rules, $messages)) {
            $alert = $invalid;
            echo '<div class="uk-text-left uk-alert-danger" uk-alert>';
            foreach ($alert as $alertmessage) {
                echo "<p>" . $alertmessage . "</p>";
            echo "</div>";
        // the data is fine, let's send the email
        } else {
            try {
                    'template' => 'email',
                    'from'     => esc($site->email()),
                    'replyTo'  => $data['email'],
                    'to'       => esc($targetmail),
                    'subject'  => '[evh-website] ' . esc($data['name']) . ' ' . esc($site->labelEmailSubject()->or('sent you a message from your contact form')),
                    'data'     => [
                        'text'   => esc($data['text']),
                        'sender' => esc($data['name'])
            } catch (Exception $error) {
                  echo "error";

            // no exception occured, let's send a success message
            if (empty($alert) === true) {
                $data = [];
                echo "success";
1 Like