Plugin to Snippet

Hello there,
i am struggling with turning a Plugin that finds a custom tag and its value in a Kirbytext-Block and replaces it with a matching structure field entry. Here is the plugin (from: Sidenotes / Marginnotes in Kirby - #6 by bruno)

    'tags' => [
        'sn' => [
            'html' => function($tag) {
                $sidenotes = $tag->parent()->sidenotes()->toStructure();
                $return = '';
                if ($sidenotes 
                && $note = $sidenotes->nth($tag->value() - 1)) {
                    $text = $note->text()->kirbyText();
                    $text = preg_replace( '/^<[^>]+>|<\/[^>]+>$/', '', $text);
                    $return = '<label for="sn-' . $tag->value . '" class="sidenote-number"></label><input type="checkbox" id="sn-' . $tag->value . '" class="margin-toggle"/><span class="sidenote">' . $text . '</span>';
                    $return = $return;
                }
                return $return;
            }
        ],
    ],

However, this plugin only works for a page with one text and one sidenote structure field.
I would like to use it also on a page that loads multiple texts with different structure fields connected. Thats why i need to turn this plugin into a snippet function that needs 2 parameters: the block to skim through and the connected structure field containing the sidenotes. But i have absolutely no idea how i would structure such a function. I have not been able to search for the tags within a given block. There must be some kind of loop available, that finds all tags containing (sn: xx) and checks them back with the given structure fieldโ€ฆ

Not sure I really understand. but would it be enough to either use a combined value like

(sn: sidenotes1:5)

where the string before the colon denotes the name of the field and the number after the colon the entry number.

Or you introduce a second attribute

(sn: 5 field: sitesnotes1)

In both cases, adapt the plugin accordingly.

Eg. for the first example:

'tags' => [
        'sn' => [
            'html' => function($tag) {
                $values = Str::split($tag->value(), ':');

                $sidenotes = $tag->parent()->{$values[0]}()->toStructure();
                $return = '';
                if ($sidenotes->count()
                && $note = $sidenotes->nth($values[1] - 1)) {
                    $text = $note->text()->kirbyText();
                    $text = preg_replace( '/^<[^>]+>|<\/[^>]+>$/', '', $text);
                    $return = '<label for="sn-' . $values[1]  . '" class="sidenote-number"></label><input type="checkbox" id="sn-' . $values[1]  . '" class="margin-toggle"/><span class="sidenote">' . $text . '</span>';
                    $return = $return;
                }
                return $return;
            }
        ],
    ],

Thanks @texnixe !!
The reason i wanted to build a function in a snippet is, that i have templates, that have only one text + sidenotes and i have templates that can contain multiple texts + sidenotes.
The plugin will work on all templates the same way and with your proposed solution, i would have to do a lot of redundant work on pages with only one text (sn: sidenotes1:1) (sn: sidenotes1:2).
I now use a function like this:

<?php

	function sidenotes($block, $sidenotes) {
		$sidenotes = $sidenotes->toStructure();
		$block = preg_replace_callback('|\(sn:[1-9]\)|', function($sidenote) use ($sidenotes) {
			$number = str_replace('(sn:', '', $sidenote[0]);
			$number = str_replace(')', '', $number);
			if ($sidenotes && $sidenotes->isNotEmpty() && $note = $sidenotes->nth($number - 1)) {
				$text = $note->text()->kirbyText();
				$text = preg_replace( '/^<[^>]+>|<\/[^>]+>$/', '', $text);
				return '<label for="sn-' . $sidenote[0] . '" class="sidenote-number"></label><input type="checkbox" id="sn-' . $sidenote[0] . '" class="margin-toggle"/><span class="sidenote">' . $text . '</span>';
			}
		}, $block);
		echo $block;

	}
?>

and just call it like this:

<? sidenotes($block, $page->sidenotes()); ?>

might not be the most elegant solution, but it works for me (at the moment) :slight_smile:

As always: Many thanks for the swift response.