Repository source: docs/plans/archive/php_template_extraction_plan_v1.md
PHP Template Extraction Plan V1
This document describes how to move HTML out of application logic code while keeping the generated HTML easy to inspect in browser "view source".
Progress
Branch:
feature/template-extractionStatus: completed
Slice 1: completed
Slice 2: completed
Slice 3: completed
Slice 4: completed
Verification:
php tests/run.phppassed after Slice 4
Goals
Keep route and application logic separate from HTML templates.
Make page HTML easy to read in source form.
Preserve the current PHP-first runtime model.
Avoid introducing a heavy framework or opaque templating layer.
Non-Goals
Do not change route ownership or response semantics.
Do not redesign the visual system as part of this refactor.
Do not introduce client-side rendering for page content.
Do not minify server-rendered HTML.
Desired End State
The application should follow a simple rendering pipeline:
route/application code loads data
route/application code selects a template
route/application code passes a small view-model array to a renderer
a shared layout template wraps the page template
reusable fragments live in partial templates
Application.php should stop assembling large HTML strings inline.
Template Structure
Recommended layout:
templates/
layout.php
partials/
nav.php
feedback.php
post_card.php
pages/
board.php
thread.php
post.php
profile.php
compose_thread.php
compose_reply.php
account_key.php
instance.php
activity.php
Renderer Design
Add a minimal renderer class, for example:
src/ForumRewrite/View/TemplateRenderer.php
Responsibilities:
load page templates from
templates/pages/load the shared layout template
expose a small set of helpers such as HTML escaping
keep rendering deterministic and simple
Suggested shape:
$renderer->renderPage('thread.php', [
'title' => $title,
'active_section' => 'board',
'script_paths' => ['/assets/openpgp.min.js', '/assets/browser_signing.js'],
'thread' => $thread,
'posts' => $posts,
]);
The renderer should use plain PHP templates and output buffering, not string concatenation inside route methods.
Template Rules
Templates should be plain PHP plus readable HTML.
Templates should receive prepared data, not query the database directly.
Templates should use an escaping helper for all untrusted values.
Templates should avoid hidden logic beyond simple conditionals and loops.
Shared fragments should move into partials instead of repeating markup.
View Source Readability Rules
To keep browser "view source" readable:
do not minify HTML
preserve indentation and line breaks
prefer one structural element per line where practical
keep scripts and styles external
keep semantic wrappers and stable class names
avoid giant concatenated strings and inline HTML fragments inside PHP logic
The generated HTML should closely resemble the template file structure.
Migration Strategy
Use incremental extraction rather than a one-shot rewrite.
Slice 1
add
TemplateRendereradd
templates/layout.phpmigrate board page
migrate thread page
status: completed
This proves the rendering model and extracts the shared shell.
Slice 2
extract post page
extract instance page
extract activity page
extract shared nav and post-card partials
status: completed
Slice 3
extract profile page
extract account-key page
extract compose thread/reply pages
extract feedback partial
status: completed
Slice 4
remove obsolete inline HTML builders from
Application.phptighten helper boundaries
update tests if they rely on exact inline formatting
status: completed
Application Responsibilities After Refactor
Application.php should remain responsible for:
routing
request parsing
calling write services
querying read-model data
selecting templates
choosing status codes and redirects
Templates should be responsible only for presentation.
Risks
accidental behavior drift while moving HTML out of string builders
duplicated escaping if helper boundaries are unclear
too much logic leaking into templates
These risks are controlled by migrating route-by-route and keeping the renderer minimal.
Testing Expectations
After each migration slice:
existing smoke tests should still pass
generated page HTML should still contain the same important route markers and assets
manual browser "view source" inspection should confirm readable indentation and structure
Recommendation
Start with the shared layout plus the board/thread pages first. They cover the common shell and repeated content patterns without the extra complexity of compose/account flows.
Progress Notes
Slice 1 completed:
added
TemplateRenderermoved shared shell/layout into
templates/layout.phpmoved board page into
templates/pages/board.phpmoved thread page into
templates/pages/thread.phpkept non-migrated routes on the same shared layout while leaving their page markup in
Application.php
Slice 2 completed:
extracted
templates/partials/nav.phpextracted
templates/partials/post_card.phpmoved post page into
templates/pages/post.phpmoved instance page into
templates/pages/instance.phpmoved activity page into
templates/pages/activity.php
Slice 3 completed:
extracted
templates/partials/feedback.phpmoved profile page into
templates/pages/profile.phpmoved account-key page into
templates/pages/account_key.phpmoved compose thread/reply pages into
templates/pages/compose_thread.phpandtemplates/pages/compose_reply.php
Slice 4 completed:
removed the obsolete inline post-card builder from
Application.phpmoved not-found, method-not-allowed, and redirect pages into templates
kept RSS serialization in code while ending HTML page assembly inside
Application.phpverified the full suite after the final cleanup pass