Replace placeholders in content text with field values, e.g. {{start}}

We just transitioned from K2 to K3. I noticed that in some content files in textarea-elements there are strings like {{start}} or {{end}} contained which in K2 would be replaced by the value of the actual field in the blueprint - as it seems, simply by calling $page->beschreibung()->kirbytext() in the template.

However, in K3 the strings are displayed unchanged in the frontend view - i.e. the front end text reads literally

…{{start}}…

Can some one please help me which function achieved the placeholder replacement in K2 and how I can get the same result in K3?

http://k2.getkirby.com/docs/developer-guide/kirbytext/filters

The replacements should be: https://getkirby.com/docs/reference/plugins/hooks/kirbytext-before

Great! And how can I find out, which page is called in the current request so I can only filter on certain pages?

Would have to look into that, but alternatively, you can also use Str::template() where needed:

<?= Str::template($page->beschreibung()->kt(), [
  'start' => $page->start()->toDate('d.m.Y'),
  'end'   => $page->end()->toDate('d.m.Y')
]); ?>
1 Like

@texnixe this did the trick, thanks!

However, I find it quite concerning, that there seems to be a regression in many parts from K2 to K3 with this as the latest example: K2 filters provide a $kirbytext argument which gives access to the $page object, the corresponding K3 hook doesn’t.

And just to mention one more example: the enormous growth of complexity to customize a simple field in a blueprint in K3 (compared to K2). And this is not 3.0, this is now 3.3. And still there are so many things which are now much harder for the developer. @bastianallgeier are you considering this at all? How come this happened?

I didn’t say that, I said I had to look into this, because I don’t know everything. Turns out, you have access to the $this object, with is the Kirby instance, which gives you access to the $site object and the current page, e.g.

  'hooks' => [
        'kirbytext:before' => function ($text) {
            dump($this->site()->page());
            return $text;
        }
    ],

(And it is not documented…)

@texnixe:
I want to follow your hints by using an own K3 plugin in my upgrade website.

At https://getkirby.com/docs/reference/plugins/hooks/kirbytags-before I have found:

return [
    'hooks' => [
        'kirbytags:before' => function ($text, $data, $options) {
            // your code goes here
        }
    ]
]

At A complex example I have found:

Kirby::plugin('superwoman/superplugin', [
  'snippets' => [
    'header' => __DIR__ . '/snippets/header.php'
  ],
  'templates' => [
    'blog' => __DIR__ . '/templates/blog.php'
  ],
  'hooks' => [
    'page.delete:before' => function () {
      throw new Exception('Nope');
    }
  ]
]);

So I tried this in a file index.php of an own new K3 plugin directory:

<?php
Kirby::plugin('test/textsnippets', [
  'hooks' => [
    'kirbytext:before' => function ($text, $data, $options) {
      // your code goes here
      return $text;
    }
  ],
]);

Now I have a problem, I get the whoops message:

ArgumentCountError thrown with message "Too few arguments to function Kirby\Cms\App::{closure}(), 1 passed and exactly 3 expected"

But I think looking at my old Kirby 2 code, I need more than one argument. I am doing something wrong.

The hook takes only one argument, at least according to the documentation.

Sorry, I can not understand your message:

Is https://getkirby.com/docs/reference/plugins/hooks/kirbytags-before not the correct link for my problem? I thought this is the correct link (including plugins/hooks in the link).

And how can I get the content between the two {{ }} in my plugin?

There are two different hooks, kirbytext.before and kirbytags.before with different arguments.

1 Like

Thank you, that is different.

But how can I get the content between the two {{ }} in my plugin?

By passing the $text argument to Str::template().

Excuse me, I still don’t get this in my context.

My plugin code now looks like this:

<?php
Kirby::plugin('test/textsnippets', [
  'hooks' => [
    'kirbytext:before' => function ($text) {
      $bracket_content = ???;
      // the next code goes here...
      return $text;
    }
  ],
]);

Please add the needed code to get the content between the brackets at the ??? or change the other code.

It’s the same code as Replace placeholders in content text with field values, e.g. {{start}}

and in the example I linked to.

What you have in your brackets is the key. You return Str::template() with the arguments, i.e. the text and your replacements as array of key /value pairs.

Sorry, we may be write about two different things.

I need https://k2.getkirby.com/docs/developer-guide/kirbytext/filters running on Kirby 3. This is your first link in your first post on this page.

The {{ }} is in my case part of the field $text in function ($text). And sometime there are more than one {{ }} in the field $text.
And the replacements are in the config file and not in the fields of the current page.

Or can you provide a new Kirby 3 recipe for this soon?

The answer is already in the above, you use the Str::template() method and return that from the hook.

'kirbytext:before' => function ($text) {
     return  Str::template($text, [
         'key1'   => 'some value',
         'key2'   => 'some other value'
     ]);
}

Exactly like in the example plugin I already linked to above, where the keys are the placeholders to replace with the values.

Thank you for your hints.

To document the result:

Using https://k2.getkirby.com/docs/developer-guide/kirbytext/filters with Kirby 3:

The config file /site/config/config.php results in:

<?php

return [ // Make sure to only use a single "return" statement in this file !!!

  // other config settings

  // https://k2.getkirby.com/docs/developer-guide/kirbytext/filters
  'kirbytext.snippets' => [
    'email' => 'bastian@getkirby.com',
    'lorem' => 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam 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, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.',
  ],

  // other config settings

];

The plugin file /site/plugins/textsnippets/index.php looks like:

<?php
// https://k2.getkirby.com/docs/developer-guide/kirbytext/filters

Kirby::plugin('heineref/textsnippets', [
  'hooks' => [
    'kirbytext:before' => function ($text) {
      $snippets = option('kirbytext.snippets', []);

      return  Str::template($text, $snippets);
    }
  ],
]);

@texnixe:
Feel free to use this to build a Kirby 3 recipe, if you want.