Another option that doesn't require rewriting templates would be to create a custom Cell
class that uses a CellView
class. The view class then wraps the cell contents in a layout which can display blocks like you would normally expect in Cake view/layout templating.
<?php
declare(strict_types=1);
namespace App\View;
use Cake\View\Cell as BaseCell;
use Cake\View\View;
class Cell extends BaseCell
{
/**
* @inheritDoc
*/
public function createView(?string $viewClass = null): View
{
// use custom CellView to for Cells
return parent::createView(CellView::class);
}
}
Then the CellView:
<?php
declare(strict_types=1);
namespace App\View;
class CellView extends AppView
{
/**
* @inheritDoc
*/
public function render(?string $template = null, $layout = null): string
{
$cellContents = parent::render($template, $layout);
// wrap cell contents in "cell" layout
return $this->renderLayout($cellContents, 'cell');
}
}
Now that all cells use a layout, all that is left is to create a basic layout used exclusively by cells:
/templates/layout/cell.php (CakePHP 3: /src/Template/Layout/cell.ctp)
<?php
/**
* @var CellView $this
*/
use App\View\CellView;
echo $this->fetch('styles');
echo $this->fetch('content');
echo $this->fetch('scripts');
After this initial work, all App\View\Cell
s will use the "cell" layout. I've found this is a bit more intuitive in the long run if you use different blocks or postLink
s with blocks.
Note: The code here is for CakePHP 4 but all you should need to do to make it CakePHP 3 compatible is match the method signatures