Laminas ViewModel

Code
<?php

define
('NL'PHP_EOL PHP_EOL);

use 
Laminas\View\Renderer\PhpRenderer;
use 
Laminas\Escaper\Escaper;
use 
Laminas\View\Model\ViewModel;
use 
Laminas\View\Resolver\TemplatePathStack;
use 
Laminas\View\View;

// usually you escape template variables too
echo '- how the templates look like:' NL;
$baseTemp __DIR__ '/templates/base.phtml';
$leftTemp __DIR__ '/templates/left.phtml';
$rightTemp __DIR__ '/templates/right.phtml';

$esc = new Escaper();
echo 
$esc->escapeHtml(file_get_contents($baseTemp)) . NL;
echo 
$esc->escapeHtml(file_get_contents($leftTemp)) . NL;
echo 
$esc->escapeHtml(file_get_contents($rightTemp)) . NL;

// ----- snippet for using ViewModel -----

$left = new ViewModel(array('value' => 'lefty'));
$left->setTemplate('left');

$right = new ViewModel(array('value' => 'righty'));
$right->setTemplate('right');

$base = new ViewModel();
$base->setTemplate('base');
// "has_parent" is important for rendering its children
$base->setOption('has_parent'true);

$base->addChild($left'left_td')
    ->
addChild($right'right_td');

// ----- snippet for rendering -----

$func = function() {
    
$resolver = new TemplatePathStack();
    
$resolver->addPath(__DIR__ '/templates');

    
$renderer = new PhpRenderer();
    
$renderer->setResolver($resolver);
    
    return 
$renderer;
};

$view = new View();
// expects callable, not one of the Laminas\View\Strategy
$view->addRenderingStrategy($func);
echo 
'- rendering the view models:' NL;
echo 
$view->render($base);
Result
- how the templates look like:

<table border="1"><tr><td><?php echo $this->left_td ?></td><td><?php echo $this->right_td ?></td></tr></table>

<strong>left value: <?php echo $this->value ?></strong>

<em>right value: <?php echo $this->value ?></em>

- rendering the view models:

left value: leftyright value: righty
Used Versions
PHP 8.2, Laminas MVC 3.2, Symfony 5.2, Laravel 8.28, PHPUnit 9.5, Doctrine ORM 2.8