v0.1.1 - Bootstrap frontend rendering via Twig templates
All checks were successful
Create Release Package / PHP Lint (push) Successful in 49s
Create Release Package / Build Release (push) Successful in 1m18s

Replace FSE block markup on the frontend with proper Bootstrap 5 HTML
rendered through Twig templates. The Site Editor remains functional for
admin editing while the public site outputs Bootstrap navbar, cards,
pagination, grid layout, and responsive components.

New PHP classes: TemplateController, ContextBuilder, NavWalker
New Twig templates: 20 files (base, pages, partials, components)
Enhanced TwigService with WordPress functions and globals

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-02-08 15:11:00 +01:00
parent d069a203b4
commit cb288d6e74
32 changed files with 1439 additions and 29 deletions

16
views/pages/404.html.twig Normal file
View File

@@ -0,0 +1,16 @@
{% extends 'base.html.twig' %}
{% block content %}
<div class="container text-center py-5">
<h1 class="display-1 fw-bold text-body-secondary">404</h1>
<h2 class="mb-3">{{ __('Page not found') }}</h2>
<p class="lead text-body-secondary mb-4">
{{ __('The page you are looking for does not exist, or it has been moved. Please try searching using the form below.') }}
</p>
<div class="row justify-content-center">
<div class="col-md-6">
{% include 'partials/search-form.html.twig' %}
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,12 @@
{% extends 'base.html.twig' %}
{% block content %}
<div class="container">
<h1 class="mb-2">{{ archive.title|raw }}</h1>
{% if archive.description %}
<div class="lead text-body-secondary mb-4">{{ archive.description|raw }}</div>
{% endif %}
{% include 'components/post-loop.html.twig' %}
</div>
{% endblock %}

View File

@@ -0,0 +1,20 @@
{% extends 'base.html.twig' %}
{% block content %}
<div class="container">
<h1 class="mb-4">{{ __('Blog') }}</h1>
{% if layout == 'sidebar' %}
<div class="row">
<div class="col-lg-8">
{% include 'components/post-loop.html.twig' %}
</div>
<div class="col-lg-4">
{% include 'partials/sidebar.html.twig' %}
</div>
</div>
{% else %}
{% include 'components/post-loop.html.twig' %}
{% endif %}
</div>
{% endblock %}

View File

@@ -0,0 +1,20 @@
{% extends 'base.html.twig' %}
{% block content %}
<div class="container">
<article class="py-4">
{% if post.thumbnail %}
<figure class="mb-4">
<img src="{{ post.thumbnail }}" class="img-fluid rounded"
alt="{{ post.title|e('html_attr') }}">
</figure>
{% endif %}
<h1>{{ post.title }}</h1>
<div class="post-content">
{{ post.content|raw }}
</div>
</article>
</div>
{% endblock %}

View File

@@ -0,0 +1,15 @@
{% extends 'base.html.twig' %}
{% block content %}
<div class="container">
<h1 class="mb-4">
{{ __('Search results for: %s')|format('<em>' ~ search_query ~ '</em>')|raw }}
</h1>
{% include 'partials/search-form.html.twig' %}
<div class="mt-4">
{% include 'components/post-loop.html.twig' %}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,50 @@
{% extends 'base.html.twig' %}
{% block content %}
<div class="container">
<article class="py-4">
<header class="mb-4">
<h1>{{ post.title }}</h1>
{% include 'partials/meta.html.twig' %}
</header>
{% if post.thumbnail %}
<figure class="mb-4">
<img src="{{ post.thumbnail }}" class="img-fluid rounded"
alt="{{ post.title|e('html_attr') }}"
style="aspect-ratio: 16/9; object-fit: cover; width: 100%;">
</figure>
{% endif %}
<div class="post-content">
{{ post.content|raw }}
</div>
{% if post.tags|length > 0 %}
<div class="mt-4 mb-4">
{% for tag in post.tags %}
<a href="{{ tag.url }}" class="badge bg-secondary text-decoration-none me-1">
{{ tag.name }}
</a>
{% endfor %}
</div>
{% endif %}
{% include 'partials/post-navigation.html.twig' %}
{% include 'partials/comments.html.twig' %}
</article>
{% if more_posts is defined and more_posts|length > 0 %}
<section class="py-5 border-top">
<h2 class="h4 mb-4">{{ __('More posts') }}</h2>
<div class="row row-cols-1 row-cols-md-3 g-4">
{% for post in more_posts %}
<div class="col">
{% include 'components/card-post-grid.html.twig' with {'post': post} only %}
</div>
{% endfor %}
</div>
</section>
{% endif %}
</div>
{% endblock %}