KirbyTag Plugin: Code outsourcing problem

Hi,
I am on rewriting my existing website to Kirby 3. It was developed a few years ago using Kirby 2. It is a company website making heavy use of tables for displaying all kinds of technical data.

I am now at the point where I need to have my table plugin working. It is based on the K2 table plugin by Julien Gargot, which is no longer existing in K3. I modified this plugin in several ways to get comfortable table layouts with head/body, style and formatting attributes.

It basically works as follows:

(table…)Text to be modified(…table)

where the text between (table…) and (…table) gets replaced by some HTML table syntax.

As a base for K3, I took the culomns example plugin Columns in Kirbytext | Kirby which works the pretty similar way:
The text between:
(columns…) Left column ++++ Right column (…columns)
gets replaced by some HTML code.

The code is as given in the example:
In /site/plugins/table/index.php:

<?php
Kirby::plugin('kirby/columns', [
'hooks' => [
'kirbytags:before' => function ($text, array $data = []) {

  $text = preg_replace_callback('!\(columns(…|\.{3})\)(.*?)\((…|\.{3})columns\)!is', function($matches) use($text, $data) {

    $columns        = preg_split('!(\n|\r\n)\+{4}\s+(\n|\r\n)!', $matches[2]);
    $html           = [];
    $classItem      = $this->option('kirby.columns.item', 'column');
    $classContainer = $this->option('kirby.columns.container', 'columns');

    foreach ($columns as $column) {
        $html[] = '<div class="' . $classItem . '">' . $this->kirbytext($column, $data) . '</div>';
    }

    return '<div class="' . $classContainer . '">' . implode($html) . '</div>';

  }, $text);

  return $text;
}
]
]);

and it works as it should.

Now I want to outsource the code as shown in KirbyTags | Kirby because I have some different modifications of my table tag, and I want a single file for each.

In /site/plugins/table/index.php:

Kirby::plugin('kirby/table', [
'hooks' => [
	'columns' => require_once __DIR__ . '/tags/columns.php'
    ]
]);

and in /site/plugins/table/tags/columns.php the rest of the example code:

return [
 'kirbytags:before' => function ($text, array $data = []) {

  $text = preg_replace_callback('!\(columns(…|\.{3})\)(.*?)\((…|\.{3})columns\)!is', function($matches) use($text, $data) {

    $columns        = preg_split('!(\n|\r\n)\+{4}\s+(\n|\r\n)!', $matches[2]);
    $html           = [];
    $classItem      = $this->option('kirby.columns.item', 'column');
    $classContainer = $this->option('kirby.columns.container', 'columns');

    foreach ($columns as $column) {
        $html[] = '<div class="' . $classItem . '">' . $this->kirbytext($column, $data) . '</div>';
    }

    return '<div class="' . $classContainer . '">' . implode($html) . '</div>';

  }, $text);

  return $text;
}

];

But this way nothing happens to the (columns…) (…columns) tags at all. It ends up completely unmodified in the HTML output.

When I place a little syntax error in the index.php or the culomns.php, I get error messages, so I know that both files are pulled; but nothing happens to the tag.

Well,this is not a tags but a hook. You can either return an array of hooks, or a function per hook.

table/index.php

<?php
Kirby::plugin('kirby/table', [
  'hooks' => [

	'kirbytags:before' => [
         // you can pass an array of functions here
          require __DIR__ . '/hooks/columns.php',
          require __DIR__ . '/hooks/table.php',
         // ...
    ]
  ]
]);

table/hooks/columns.php

<?php

return function ($text, array $data = []) {

  $text = preg_replace_callback('!\(columns(…|\.{3})\)(.*?)\((…|\.{3})columns\)!is', function($matches) use($text, $data) {

    $columns        = preg_split('!(\n|\r\n)\+{4}\s+(\n|\r\n)!', $matches[2]);
    $html           = [];
    $classItem      = $this->option('kirby.columns.item', 'column');
    $classContainer = $this->option('kirby.columns.container', 'columns');

    foreach ($columns as $column) {
        $html[] = '<div class="' . $classItem . '">' . $this->kirbytext($column, $data) . '</div>';
    }

    return '<div class="' . $classContainer . '">' . implode($html) . '</div>';

  }, $text);

  return $text;
};

Thank you @texnixe, this works! Now I can go on and reuse my old table code. Also I can put different hooks into a single plugin. This is much more convenient than to have a separate plugin for each hook.