# Maximum function nesting level of '256' reached, aborting!

**URL:** <https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603>\
**Category:** Questions\
**Tags:** v3\
**Created:** [December 8, 2019, 12:01pm UTC](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603 "2019-12-08T12:01:24Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![coko](https://avatars.discourse-cdn.com/v4/letter/c/f17d59/32.png) [@coko](https://forum.getkirby.com/u/coko)\
**Post date:** [December 8, 2019, 12:01pm UTC](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603/1 "2019-12-08T12:01:24Z")

</div>

(Kirby v 3.3.0)

Taking the `{{ gallery }}` tag as an example, I’m making a `{{ accordion }}` tag.

But I’m running into this error: `Maximum function nesting level …` when I’m trying to display the accordion content panel.

- This **doesn’t** work: `<?= $item->accordion_content()->kt() ?>`
- This **does** work: `<?= $item->accordion_content()->md() ?>`

Using `md()` will limit me in the display of (custom) KirbyTags so I’d rather not use it.

Blueprint:

```auto
accordion:
  label: Accordion
  type: structure
  fields:
    accordion_heading:
      label: Heading
      type: text
    accordion_content:
      label: Content
      type: textarea
      buttons:
        - italic
        - bold
        - link
        - '|'
        - email
        - file
        - code 
        - '|'
        - ul
        - ol

```

Plugin (plugins/accordion/index.php):

```auto
<?php Kirby::plugin('kirby/accordion', [
    'hooks' => [
        'kirbytags:after' => function ($text, $data, $options) {

            if ($page = $data['parent']->accordion()->toStructure()) {
                $items = snippet('accordion', ['items' => $page], true);
            } else {
                $items = '';
            }

            return str_replace('{{ accordion }}', $items, $text);
        }
    ]
]);

```

Snippet (snippets/accordion.php) that doesn’t work:

```auto
<div id="accordionGroup" class="accordion" data-allow-toggle>
<?php 
    $n=0;
    foreach ($items as $item): $n++; 
?>
<h3>
  <button aria-expanded="<?= e($n > 1, 'false', 'true') ?>" class="accordion-trigger" aria-controls="<?= 'sect' . $n ?>" id="<?= 'accordion' . $n . 'id' ?>">
    <span class="accordion-title">
        <?= $item->accordion_heading()->html() ?>
        <span class="accordion-icon"></span>
    </span>
  </button>
</h3>
<div id="<?= 'sect' . $n ?>" role="region" aria-labelledby="<?= 'accordion' . $n . 'id' ?>" class="accordion-panel" <?= e($n > 1, 'hidden=""', '') ?>>
<div>
  <?= $item->accordion_content()->kt() ?>
</div>
</div>
<?php endforeach ?>
</div>

```

I remember running into this problem before and was able to solve it with something like: `<?= kt($item->accordion_content()) ?>` but that doesn’t help in this case.

Also I noticed: using the snippet with 4 spaces indentation will break my layout because `<pre>` tags are placed at certain points in the markup of the accordion.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [December 8, 2019, 12:27pm UTC](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603/2 "2019-12-08T12:27:38Z")

</div>

You are running into an endless loop because you are trying to call the `kirbytext()` method inside your snippet, which will then trigger the hook etc.

---

<div class="post-metadata">

**Author:** ![coko](https://avatars.discourse-cdn.com/v4/letter/c/f17d59/32.png) [@coko](https://forum.getkirby.com/u/coko)\
**Post date:** [December 8, 2019, 12:29pm UTC](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603/3 "2019-12-08T12:29:06Z")

</div>

Of course, thanks.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [December 8, 2019, 1:31pm UTC](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603/4 "2019-12-08T13:31:37Z")

</div>

You can replace your hook code like this:

```auto
Kirby::plugin('kirby/accordion', [
    'hooks' => [
        'kirbytags:before' => function ($text, $data) {

            return preg_replace_callback('!{{(.*)}}!siU', function($match) use ($data) {
                $block = '';
                if ($items = $data['parent']->accordion()->toStructure()) {
                    $block = snippet('accordion', ['items' => $items]);
                }
                return $block;

            }, $text);
           
        }
    ]
]);

```

---

<div class="post-metadata">

**Author:** ![coko](https://avatars.discourse-cdn.com/v4/letter/c/f17d59/32.png) [@coko](https://forum.getkirby.com/u/coko)\
**Post date:** [December 8, 2019, 2:22pm UTC](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603/5 "2019-12-08T14:22:48Z")

</div>

I had already given up on it, cool thanks a bunch! 💯

---

<div class="post-metadata">

**Author:** ![coko](https://avatars.discourse-cdn.com/v4/letter/c/f17d59/32.png) [@coko](https://forum.getkirby.com/u/coko)\
**Post date:** [December 8, 2019, 2:58pm UTC](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603/6 "2019-12-08T14:58:49Z")

</div>

Just tried this: this places two accordions on the page. One before and one after a cover image.  
Also doesn’t play nicely with the `{{ gallery }}` tag, breaks it.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [December 8, 2019, 3:23pm UTC](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603/7 "2019-12-08T15:23:02Z")

</div>

Oh, I applied that to every tag, should of course just apply to the accordion tag:

```auto
   'kirbytags:before' => function ($text, $data) {

            return preg_replace_callback('!{{ accordion }}!siU', function($match) use ($data) {
                $block = '';
                if ($items = $data['parent']->accordion()->toStructure()) {
                    $block = snippet('accordion', ['items' => $items]);
                }
                return $block;

            }, $text);
           
        }

```

You might want to adapt the regex to make sure it also works when the user doesn’t use spaces between the curly braces.

---

<div class="post-metadata">

**Author:** ![coko](https://avatars.discourse-cdn.com/v4/letter/c/f17d59/32.png) [@coko](https://forum.getkirby.com/u/coko)\
**Post date:** [December 8, 2019, 3:29pm UTC](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603/8 "2019-12-08T15:29:20Z")

</div>

Yes, I already tried that, but it doesn’t solve the double accordion.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [December 8, 2019, 4:36pm UTC](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603/9 "2019-12-08T16:36:32Z")

</div>

Hm, I can’t reproduce the double accordion.

---

<div class="post-metadata">

**Author:** ![coko](https://avatars.discourse-cdn.com/v4/letter/c/f17d59/32.png) [@coko](https://forum.getkirby.com/u/coko)\
**Post date:** [December 8, 2019, 4:45pm UTC](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603/10 "2019-12-08T16:45:13Z")

</div>

When I trash this toc-code it works:  
Can you see the problem?

```auto
<?php Kirby::plugin('kirby/toc', [
    'fieldMethods' => [
        'headlines' => function($field, $headline = 'h2') {
            preg_match_all('!<' . $headline . '.*?>(.*?)</' . $headline . '>!s', $field->kt()->value(), $matches);
                    $headlines = new Collection;
                    foreach ($matches[1] as $text) {
                        $headline = new Obj([
                            'id' => $id = '#' . Str::slug(Str::unhtml($text)),
                            'url' => $id,
                            'text' => trim(strip_tags($text)),
                        ]);
                        $headlines->append($headline->url(), $headline);
                    }
                    return $headlines;
        }
    ]
]);

```

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [December 8, 2019, 6:14pm UTC](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603/11 "2019-12-08T18:14:49Z")

</div>

No, you took that code from the [getkirby.com](http://getkirby.com) repo, right?

I can reproduce your issue with the duplicate accordions when I use the `headlines` method in the same template, but I currently don’t know how to solve this.

---

<div class="post-metadata">

**Author:** ![coko](https://avatars.discourse-cdn.com/v4/letter/c/f17d59/32.png) [@coko](https://forum.getkirby.com/u/coko)\
**Post date:** [December 8, 2019, 6:32pm UTC](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603/12 "2019-12-08T18:32:50Z")

</div>

That’s right, it was from a thread where you explained how to use it and I followed that example.  
I will use the markdown version for now and maybe you will have a 💡 moment.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [December 8, 2019, 7:05pm UTC](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603/13 "2019-12-08T19:05:43Z")

</div>

If you don’t call your `headlines()` method directly in the same template, but in a snippet like in the. [getkirby.com](http://getkirby.com) repo, it should work:

`/snippets/toc.php`

```auto
<?php if($item->count() > 3): ?>
  <nav class="toc | -mb:large">

    <h2 class="h4">Table of Contents</h2>

    <ol>
      <?php foreach($item as $headline): ?>
        <li><a href="<?= $headline->url() ?>"><span><?= $headline->text() ?></span></a></li>
      <?php endforeach ?>
    </ol>

  </nav>
<?php endif ?>

```

And in template

```auto
snippet('toc', $page->description()->headlines())

```

---

<div class="post-metadata">

**Author:** ![coko](https://avatars.discourse-cdn.com/v4/letter/c/f17d59/32.png) [@coko](https://forum.getkirby.com/u/coko)\
**Post date:** [December 8, 2019, 7:18pm UTC](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603/14 "2019-12-08T19:18:28Z")

</div>

Currently:

- plugin: `plugins/toc/index.php`
- snippet: `toc.php` (code where I have conditionals at work to combine toc with cover image)
- snippet: `page-content.php` where I call: `snippet('toc', $page->text()->headlines())` more stuff in here though
- page template: `snippet('page-content')`

No doubt you would clean this up and maybe this is the source of all the troubles?  
I’ll try your suggestion …

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [December 8, 2019, 7:36pm UTC](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603/15 "2019-12-08T19:36:45Z")

</div>

Actually, I had a typo in my code, so with the changes above, everything should actually work as expected. Still doesn’t in your case?

---

<div class="post-metadata">

**Author:** ![coko](https://avatars.discourse-cdn.com/v4/letter/c/f17d59/32.png) [@coko](https://forum.getkirby.com/u/coko)\
**Post date:** [December 8, 2019, 7:37pm UTC](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603/16 "2019-12-08T19:37:34Z")

</div>

Bit confused about `dump($field->headlines());` what `$field` etc.  
But what typo was that?

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [December 8, 2019, 7:41pm UTC](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603/17 "2019-12-08T19:41:15Z")

</div>

> [@coko](#):
>
> Bit confused about `dump($field->headlines());` what `$field` etc.

That was just from my first test. The code just dumps the content of `$field->headlines()`. It’s a way to check what you get back from your code. Just stick with the `toc` snippet from the [getkirby.com](http://getkirby.com) repo. I removed the [`dump()`](https://getkirby.com/docs/reference/templates/helpers/dump) code again.

> [@coko](#):
>
> But what typo was that?

Just in my local code, I made changes and forgot to add `true` as third param to a snippet, which resulted in the wrong order.

---

<div class="post-metadata">

**Author:** ![coko](https://avatars.discourse-cdn.com/v4/letter/c/f17d59/32.png) [@coko](https://forum.getkirby.com/u/coko)\
**Post date:** [December 8, 2019, 7:49pm UTC](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603/18 "2019-12-08T19:49:47Z")

</div>

snippet/toc.php:

```auto
<?php // ToC combined with cover
    if($item->count() and $page->toc()->bool() and $page->cover_toc()->bool()): ?>
    <nav class="toc-cover" aria-labelledby="toc-head">
        <div class="toc">
            <h2 class="toc-heading" id="toc-head">On this page</h2>
            <ol>
                <?php foreach($item as $headline): ?>
                    <li><a href="<?= $headline->url() ?>"><?= $headline->text() ?></a></li>
                <?php endforeach ?>
            </ol>
        </div>
        <?php // cover image
            if($cover = $page->cover()->toFile() and $page->showcover()->bool()): ?>
            <figure>
                <img src="<?= $cover->url(); ?>" srcset="<?= $cover->srcset() ?>" alt="<?= $cover->alt(); ?>">
            </figure>
        <?php endif ?>
    </nav>
<?php endif ?>

```

plugin:

```auto
<?php Kirby::plugin('kirby/toc', [
    'fieldMethods' => [
        'headlines' => function($field, $headline = 'h2') {
            preg_match_all('!<' . $headline . '.*?>(.*?)</' . $headline . '>!s', $field->kt()->value(), $matches);
                    $headlines = new Collection;
                    foreach ($matches[1] as $text) {
                        $headline = new Obj([
                            'id' => $id = '#' . Str::slug(Str::unhtml($text)),
                            'url' => $id,
                            'text' => trim(strip_tags($text)),
                        ]);
                        $headlines->append($headline->url(), $headline);
                    }
                    return $headlines;
        }
    ]
]);

```

snippet page-content:

```auto
<?php snippet('toc', $page->text()->headlines()) ?>

```

Which all worked fine but not with the accordion `{{ accordion }}` and the `preg_replace_callback`.

---

<div class="post-metadata">

**Author:** ![coko](https://avatars.discourse-cdn.com/v4/letter/c/f17d59/32.png) [@coko](https://forum.getkirby.com/u/coko)\
**Post date:** [December 8, 2019, 7:55pm UTC](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603/19 "2019-12-08T19:55:24Z")

</div>

Thanks you are amazingly kind to stick with this.  
I have to go now but again thanks for all your efforts!

---

<div class="post-metadata">

**Author:** ![coko](https://avatars.discourse-cdn.com/v4/letter/c/f17d59/32.png) [@coko](https://forum.getkirby.com/u/coko)\
**Post date:** [December 9, 2019, 5:48am UTC](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603/20 "2019-12-09T05:48:17Z")

</div>

I found the/a solution. In the toc plugin I replaced:

```auto
preg_match_all('!<' . $headline . '.*?>(.*?)</' . $headline . '>!s', $field->kt()->value(), $matches);

replaced with:

preg_match_all('!<' . $headline . '.*?>(.*?)</' . $headline . '>!s', $field->md()->value(), $matches);

```

Swapping **kt()** for **md()**.

Resulting in a nice toc and **one** accordion (including kt link):

 ![Schermafbeelding 2019-12-09 om 06.42.33](https://europe1.discourse-cdn.com/flex017/uploads/getkirby/original/2X/4/44208f524cc9fc35790ccd44edcd4d2a50ea261b.jpeg)

btw: I’m calling the toc and my page text field in the same template:

```auto
<?php // ToC and cover image see also plugins › toc
     snippet('toc', $page->text()->headlines()) ?>

<?php // page text replacing escaped opening parenthesis '(\' for kirbytext examples
     echo str_replace('(\\', '(', kirbytext($page->text())) ?>

```

[Next page](https://forum.getkirby.com/t/maximum-function-nesting-level-of-256-reached-aborting/16603.md?page=2)
