Python in, PHP arrays out, and a theme that provisions itself.
Five hundred pages are not written by hand and they are not held in a database. They are generated from Python into plain PHP arrays, committed as files, and read by a WordPress theme that creates its own pages on activation.
The pipeline, end to end.
A family is a Python module
One file per pillar. It declares its pages as data — path, title, template, and a list of sections.
Sections are function calls
Ninety-odd builders. A hero is hero(…), a comparison table is compare(…), a rights register is register(…). Nobody writes markup.
A floor is enforced at write time
Every page needs at least seven sections. A thinner one raises rather than shipping, because a stub inside five hundred pages reads as neglect.
The build serialises to PHP
One file per family in inc/content, as a plain PHP array with a return statement. Readable, diffable, and editable by hand if anybody ever needs to.
The theme reads the array
A content loader maps a request path to an entry and renders the sections in order through one template part each.
The theme provisions itself
On activation it creates the WordPress pages, assigns the templates and builds the menus from a map. No manual setup, no import file.
Why each of those decisions was taken.
Generation rather than authoring
- Consistency
- Five hundred pages, one voiceA section builder cannot be styled inconsistently, because there is one implementation of each.
- Refactoring
- A change to a section type reaches every pageChanging how a comparison table looks is one file, not four hundred edits.
- Structure
- Every page has a shapeThe seven-section floor is checkable at build time rather than in review.
- The cost
- A build step, and a learning curveSomebody who wants to fix a typo has to know where the generator is. That is a real cost.
PHP arrays rather than a database
- Diffable
- Every content change is a diffWhich is the single largest practical advantage and the one nobody expects.
- Deployable
- Content ships with codeNo import, no migration, no staging database that has drifted from production.
- Fast
- An include, and an opcode cacheNo query, no join, no cache invalidation problem.
- The cost
- Editors cannot editThis is a demonstration build with no editors. On a real one it would need an admin layer, and that is not free.
Self-provisioning
- Activation creates the pages
- From the same arraysA fresh WordPress install becomes the whole site in one click.
- Menus from a map
- Declared, not clickedA five-hundred-page menu built by hand is wrong within a week.
- Templates assigned automatically
- By the template fieldNobody picks a page template in an admin screen, so nobody picks the wrong one.
What the build actually produces.
| Artefact | What it is | Roughly |
|---|---|---|
| inc/content/*.php | One plain PHP array per family | Twenty-four files |
| page-templates/page-*.php | A thin wrapper per page type | Around ninety |
| template-parts/sections/*.php | One renderer per section type | One per builder in the generator |
| assets/js/search-index.js | The command palette index, generated at build | One cached request rather than an inline blob on every page |
| assets/img/scenes/*.svg | Generated illustrations | Fifty base scenes, no photography, nothing licensed |
| bin/qa.php | A static harness | Page counts, template coverage, broken internal links, orphans and duplicate chapter numbers |
| bin/preview.php | A static render harness | Renders every page to flat HTML without WordPress, which proves the templates execute |
The thing this stack is bad at.
Editing. There is no admin interface for content, because the content is a file. Somebody who wants to change a sentence needs the repository, a Python environment and a build step, which is a perfectly reasonable requirement for a demonstration build and a completely unreasonable one for a business with a marketing team.
A real version would need a layer that lets a person edit a page without touching a generator, and that layer is not free — it is the point at which most of the advantages above start to be traded away one at a time.
The honest position is that generation is right for a site of this shape, produced this way, at this scale, by very few people. It would be the wrong answer for a newsroom, and it would be the wrong answer for anybody who needed to publish something at four o’clock on a Friday.
Four properties, one of them a weakness.
Generated
Python modules in, PHP arrays out.
Diffable
Every content change is a diff.
A seven-section floor
Enforced at build time, not in review.
Bad at editing
And this page says so rather than not.
The stack, questioned.
Because it brings routing, templating, SEO plumbing, redirects and a hosting story that everybody already has. The content layer is replaced; the rest is genuinely useful.
Not as it stands. That is the main weakness of the approach and it is stated on this page rather than in a footnote.
Yes. One generated JavaScript file, cached once, shared by every page — rather than thirty-five kilobytes of index inlined into five hundred documents.
And the numbers behind the numbers.
Where every figure on this site came from, and which of them we are least sure about.