You've already forked wp-bootstrap
Full Design Editor compatibility with custom block categories, page templates, header/footer variations, and navigation styles. Both FSE (admin) and Twig (frontend) sides kept in sync. Co-Authored-By: Claude <noreply@anthropic.com>
107 lines
2.9 KiB
PHP
107 lines
2.9 KiB
PHP
<?php
|
|
/**
|
|
* Template Controller.
|
|
*
|
|
* Intercepts frontend requests and renders Twig templates
|
|
* with proper Bootstrap 5 HTML instead of FSE block markup.
|
|
*
|
|
* @package WPBootstrap
|
|
* @since 0.1.1
|
|
*/
|
|
|
|
namespace WPBootstrap\Template;
|
|
|
|
use WPBootstrap\Twig\TwigService;
|
|
|
|
class TemplateController
|
|
{
|
|
private ContextBuilder $contextBuilder;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->contextBuilder = new ContextBuilder();
|
|
add_action('template_redirect', [$this, 'render']);
|
|
}
|
|
|
|
/**
|
|
* Render the appropriate Twig template for the current request.
|
|
*/
|
|
public function render(): void
|
|
{
|
|
// Skip admin, REST API, and AJAX requests.
|
|
if (is_admin() || wp_doing_ajax()) {
|
|
return;
|
|
}
|
|
|
|
if (defined('REST_REQUEST') && REST_REQUEST) {
|
|
return;
|
|
}
|
|
|
|
$template = $this->resolveTemplate();
|
|
if (! $template) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
$context = $this->contextBuilder->build();
|
|
$twig = TwigService::getInstance();
|
|
|
|
echo $twig->render($template, $context);
|
|
exit;
|
|
} catch (\Throwable $e) {
|
|
// Log the error and fall back to FSE rendering.
|
|
error_log('WP Bootstrap Twig Error: ' . $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine());
|
|
if (defined('WP_DEBUG') && WP_DEBUG) {
|
|
wp_die(
|
|
'<h1>Template Rendering Error</h1>'
|
|
. '<p><strong>' . esc_html($e->getMessage()) . '</strong></p>'
|
|
. '<p>' . esc_html($e->getFile()) . ':' . esc_html($e->getLine()) . '</p>'
|
|
. '<pre>' . esc_html($e->getTraceAsString()) . '</pre>',
|
|
'Template Error',
|
|
['response' => 500]
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Determine which Twig template to render based on WordPress conditionals.
|
|
*/
|
|
private function resolveTemplate(): ?string
|
|
{
|
|
if (is_404()) {
|
|
return 'pages/404.html.twig';
|
|
}
|
|
|
|
if (is_search()) {
|
|
return 'pages/search.html.twig';
|
|
}
|
|
|
|
if (is_singular('post')) {
|
|
return 'pages/single.html.twig';
|
|
}
|
|
|
|
if (is_page()) {
|
|
$slug = get_page_template_slug();
|
|
return match ($slug) {
|
|
'page-landing' => 'pages/landing.html.twig',
|
|
'page-full-width' => 'pages/full-width.html.twig',
|
|
'page-hero' => 'pages/hero.html.twig',
|
|
'page-sidebar' => 'pages/page-sidebar.html.twig',
|
|
default => 'pages/page.html.twig',
|
|
};
|
|
}
|
|
|
|
if (is_archive()) {
|
|
return 'pages/archive.html.twig';
|
|
}
|
|
|
|
if (is_home()) {
|
|
return 'pages/index.html.twig';
|
|
}
|
|
|
|
// Fallback.
|
|
return 'pages/index.html.twig';
|
|
}
|
|
}
|