Skip to content

Instantly share code, notes, and snippets.

@koertho
Last active April 10, 2026 20:59
Show Gist options
  • Select an option

  • Save koertho/57fa98a91c88bb3fcba4a0d4d3d65290 to your computer and use it in GitHub Desktop.

Select an option

Save koertho/57fa98a91c88bb3fcba4a0d4d3d65290 to your computer and use it in GitHub Desktop.
Contao 5 Page Controller with Layout. Use Custom Controller and Templates within the contao layout. Build with reusable trait. Example replace the main section of the template. You can also replace another section and activate the content composition and add article to other template sections.
<?php
namespace App\Controller\Page;
use Contao\CoreBundle\Controller\AbstractController;
use Contao\CoreBundle\DependencyInjection\Attribute\AsPage;
use Contao\PageModel;
use Symfony\Component\HttpFoundation\Request;
#[AsPage(type: 'custom_page',path: '/custom', contentComposition: false,)]
class RegistrationStatusPageController extends AbstractController
{
use CustomPageTrait;
public function __invoke(PageModel $pageModel, Request $request): Response
{
return $this->executeRender(
$pageModel,
['request' => $request,] // pass arguments as needed, for example passed url parameters
);
}
function getContent(PageModel $pageModel, array $arguments): string
{
// do some fancy stuff
return $this->twig->render(
'@Contao_App/controller/custom.html.twig',
$context,
);
}
}
<?php
namespace App\Controller\Page;
use Contao\FrontendIndex;
use Contao\LayoutModel;
use Contao\PageModel;
use Contao\PageRegular;
use Symfony\Component\HttpFoundation\Response;
trait CustomPageTrait
{
private array $arguments;
public function executeRender(PageModel $pageModel, array $arguments = []): Response
{
$this->arguments = $arguments;
$GLOBALS['TL_HOOKS']['generatePage']['custom_page'] = [self::class, 'renderPageContent'];
$response = (new FrontendIndex())->renderPage($pageModel);
unset($GLOBALS['TL_HOOKS']['generatePage']['custom_page']);
return $response;
}
public function renderPageContent(PageModel $pageModel, LayoutModel $layout, PageRegular $pageRegular): void
{
// replace the main section of the template. Of course you replace another section
$pageRegular->Template->main = $this->getContent($pageModel, $this->arguments);
}
abstract function getContent(PageModel $pageModel, array $arguments): string;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment