Cache onpager modules width cache::set()

I created my own one pager logic, like the Modules Plugin (did not know that). And now I want to cache my entire Kirby Page. The problem now is that some modules contains forms (Uniform).

...
<?php $sections = $page->children()->visible()->sortBy('sort', 'asc'); ?>

<?php foreach ($sections as $s): ?>
    <div class="module <?= $s->intendedTemplate(); ?>" id="<?= $s->uid(); ?>">
		<?php snippet('modules/' . $s->intendedTemplate(), array('data' => $s)); ?>
    </div>
<?php endforeach; ?>
...

My idea: Set Cache to true and disable default cache for all sites.

c::set('cache', true);
c::set('cache.ignore', ['*']);

My new onepager.php template:

<?php $sections = $page->children()->visible()->sortBy('sort', 'asc'); ?>

<?php foreach ($sections as $s):

	if ($s->intendedTemplate() !== 'form') {
		$cache = cache::get($s->hash());
		if (!$cache) {
			$cache = $s;
			cache::set($s->hash(), $cache);
		}

		$s = $cache;
	}

	?>

    <div class="module <?= $s->intendedTemplate(); ?>" id="<?= $s->uid(); ?>">
		<?php snippet('modules/' . $s->intendedTemplate(), array('data' => $s)); ?>
    </div>

<?php endforeach ?>

But now I get these Errors:

Serialization of ‘Closure’ is not allowed

Are there other ways, is this solution at all useful?
Does this solution provide performance?

Thanks for your help

You are trying to cache a page object. In your use case you should cache the snippet output.

<?php foreach ($sections as $s):
  $module = cache::get($s->hash());
  if (!$module) {
    $module = snippet('modules/' . $s->intendedTemplate(), array('data' => $s), true);
    if ($s->intendedTemplate() !== 'form') {
      cache::set($s->hash(), $module);
    }
  }
?>
<div class="module <?= $s->intendedTemplate(); ?>" id="<?= $s->uid(); ?>">
  <?= $module ?>
</div>
<?php endforeach; ?>

Something like this.

Yay, that’s cool. Thank You!!

Is there a way to check if a module.de.txt somewhere uses a specific kirby tag?
My forms are stored in tags, for example (form: contact) and my templates have a lot of different amounts of textarea input fields.

You could create a function that loops through all fields and uses some regex voodoo to check if a field contains a form tag.

Thanks to both of you

This is my solution

<?php

$hash = $s->parent()->hash() . '-' . $s->hash();

$module = cache::get($hash);
if (!$module) {
    $module = snippet('themes/' . $s->intendedTemplate(), array('data' => $s, 'sub' => false), true);

    // check if form
    $c = $s->content()->raw();
    preg_match("/\(\s*form\s*:(.*?)\)/is", $c, $match);

    // get excluded templates
    $noCaching = c::get('bsh.onepager.noCaching', array());

    if (count($match) == 0 && !in_array($s->intendedTemplate(), $noCaching)) {
        // cache
        cache::set($hash, $module);
    }
}

?>

<?= $module; ?>