diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9ab7ed1..8d23fb7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,18 @@
All notable changes to this project will be documented in this file.
+## [1.0.4] - 2026-02-11
+
+### Added
+
+- `wp_bootstrap_should_render_template` filter in `TemplateController::render()` — allows plugins and child themes to prevent the theme from rendering a specific request, enabling clean separation of concerns when plugins handle their own page rendering
+
+## [1.0.3] - 2026-02-11
+
+### Fixed
+
+- Double `
` headings on pages where plugins provide their own titles — `page.html.twig` now wraps `` in `{% if post.title is not empty %}` guard so plugins can suppress it by passing empty `post.title`
+
## [1.0.2] - 2026-02-10
### Fixed
diff --git a/CLAUDE.md b/CLAUDE.md
index e64355a..b500779 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -34,7 +34,7 @@ This project is proudly **"vibe-coded"** using Claude.AI - the entire codebase w
**Note for AI Assistants:** Clean this section after the specific features are done or new releases are made. Effective changes are tracked in `CHANGELOG.md`. Do not add completed versions here - document them in the Session History section at the end of this file.
-Current version is **v1.0.2**. See `PLAN.md` for details.
+Current version is **v1.0.4**. See `PLAN.md` for details.
## Technical Stack
@@ -193,6 +193,21 @@ Build steps (in order):
## Session History
+### Session 12 — v1.0.4 Template Render Filter (2026-02-11)
+
+**Completed:** Added `wp_bootstrap_should_render_template` filter to `TemplateController::render()` for clean plugin/theme separation.
+
+**What was added:**
+
+- New `wp_bootstrap_should_render_template` filter at the top of `TemplateController::render()` — returns `true` by default, but plugins can return `false` to prevent the theme from rendering a request
+- Enables the wp-jobroom plugin to handle its own custom post types and routes without the theme's `TemplateController` racing to render first
+- Theme remains 100% standalone — the filter is a no-op when no plugin hooks into it
+
+**Key learnings:**
+
+- WordPress `template_redirect` hook priority ordering is the primary mechanism for plugin/theme rendering coordination: plugin Router at priority 5, theme TemplateController at default priority 10
+- Adding a simple filter check (`apply_filters('wp_bootstrap_should_render_template', true)`) is the cleanest decoupling mechanism — no cross-project class detection needed
+
### Session 11 — v1.0.3 Conditional Page Title (2026-02-11)
**Completed:** Made `` on page template conditional to prevent double headings when plugins provide their own titles.
diff --git a/README.md b/README.md
index 599c8b9..517ec2b 100644
--- a/README.md
+++ b/README.md
@@ -84,7 +84,7 @@ The theme uses a dual-rendering approach:
- **Site Editor (admin):** FSE block templates in `templates/` and `parts/` for visual editing
- **Frontend (public):** Twig templates in `views/` render Bootstrap 5 HTML via the `template_redirect` hook
-The `TemplateController` intercepts frontend requests and renders the appropriate Twig template with data gathered by `ContextBuilder`. FSE templates remain untouched for the WordPress admin editor.
+The `TemplateController` intercepts frontend requests and renders the appropriate Twig template with data gathered by `ContextBuilder`. Plugins can hook into the `wp_bootstrap_should_render_template` filter to prevent rendering for specific requests (e.g., when a plugin handles its own custom post types). FSE templates remain untouched for the WordPress admin editor.
### Style Variation Bridge
diff --git a/inc/Template/TemplateController.php b/inc/Template/TemplateController.php
index c1968cc..53493fa 100644
--- a/inc/Template/TemplateController.php
+++ b/inc/Template/TemplateController.php
@@ -37,6 +37,11 @@ class TemplateController
return;
}
+ // Allow plugins or child themes to prevent rendering for this request.
+ if (! apply_filters('wp_bootstrap_should_render_template', true)) {
+ return;
+ }
+
$template = $this->resolveTemplate();
if (! $template) {
return;
diff --git a/style.css b/style.css
index b760105..83839c7 100644
--- a/style.css
+++ b/style.css
@@ -7,7 +7,7 @@ Description: A modern WordPress Block Theme built from scratch with Bootstrap 5.
Requires at least: 6.7
Tested up to: 6.7
Requires PHP: 8.3
-Version: 1.0.3
+Version: 1.0.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: wp-bootstrap