Skip to content

Runnable docs site: live examples for every component#244

Merged
adamziel merged 7 commits into
trunkfrom
adamziel/gh-pages-demos
May 2, 2026
Merged

Runnable docs site: live examples for every component#244
adamziel merged 7 commits into
trunkfrom
adamziel/gh-pages-demos

Conversation

@adamziel
Copy link
Copy Markdown
Collaborator

@adamziel adamziel commented Apr 28, 2026

What it does

Adds a generated documentation site under docs/ with runnable PHP examples for every PHP Toolkit component. The site includes reference pages, a short learning path, the previous docs preserved under docs/_legacy/, and GitHub Pages deployment.

Each example is represented as a <php-snippet> block. Snippets can run in WordPress Playground, and stable examples also carry checked-in expected output so readers see useful results before Playground finishes booting.

CleanShot 2026-05-02 at 02 53 35@2x CleanShot 2026-05-02 at 02 53 32@2x

Rationale

The component READMEs document individual APIs, but they do not give readers one consistent place to browse the toolkit or try the code. This adds an executable docs surface and puts the examples under CI so sample code is less likely to drift away from the actual components.

Implementation

bin/_docs_components.py defines the generated component catalog and examples. bin/build-docs.py and bin/build-reference.py render the learn and reference pages, while bin/build-docs-bundle.sh packages the current toolkit into docs/assets/php-toolkit.zip for Playground.

docs/assets/page.js handles snippet setup, Playground blueprints, editable code blocks, expected-output rendering, and the docs navigation. bin/run-snippets.py executes snippets locally and checks or updates bin/_expected_outputs.json.

The PR also adds bin/serve-docs.py for local preview, .github/workflows/docs.yml for GitHub Pages, .github/workflows/snippet-tests.yml for snippet CI, and excludes generated docs from PHPCS.

Testing instructions

composer install
bin/run-snippets.py --check
python3 bin/build-docs.py
python3 bin/build-reference.py
python3 bin/serve-docs.py

Then open http://localhost:8787, run a few snippets, and verify that expected output is visible before Playground boots.

Eighteen pure-PHP libraries deserve docs you can poke at, not just read.
Every page on this site embeds <php-snippet> elements that boot WordPress
Playground in your browser, unzip the toolkit into it, and run examples
against the real library. Click a snippet to edit it; click Run again.

The site lives at docs/ and is generated by bin/build-docs.py from a
single content catalog. Snippets share one runtime per page via the
blueprint mechanism shipped in WordPress/wordpress-playground#3536, so
the WASM + WordPress download only happens on the first Run click.

Pages have a sticky table-of-contents built from the h2 headings, an
editable code area (contenteditable on the rendered <code> as a
stopgap until <php-snippet> ships an editable attribute upstream), and
GitHub-flavored light/dark styling.

GitHub Actions deploys docs/ to Pages on every push to trunk; the
workflow rebuilds the toolkit bundle and regenerates pages from
trunk's components.
The PHP snippets were rendered through HTML-escape, but <script type=
"application/x-php"> content is parsed as raw text — the browser does
not decode entities, so &lt;?php and &quot; were ending up in the
runner verbatim.

Each component page now has an 'All components' list above the page TOC
so you can jump between any two pages in one click. Highlighted entry
points at the current page.
Each page now ships 5–10 examples ranked simple to complex, drawn from
real problems people hit when reaching for these libraries: lazy-loading
images and stamping CSP nonces (HTML), building EPUBs and defending
against zip-slip (Zip), three-way merging a Markdown folder against a
WP database (Merge), parallel HTTP fan-out (HttpClient), syncing an
Obsidian vault into WordPress posts (Markdown + DataLiberation), and so
on. Real composition between components — Zip into InMemoryFilesystem,
Markdown into WXR — shows how the toolkit is designed to compose.

Content moved into bin/_docs_components.py so the generator stays small
and the catalog is one focused diff to extend.
The runnable-docs site lives under /docs, including a JS bundle that
phpcs tries to lint as PHP. Mirror the existing /examples exclusion.
Stacked on top of #244. Wires the docs site into
[wordpress-playground#3555](WordPress/wordpress-playground#3555),
which added an `expected-output` mechanism to the `<php-snippet>` web
component. When a snippet ships its expected output, Run renders that
output instantly without booting Playground at all — no PHP/WordPress
download, no iframe, no wait.

## How it works

`bin/run-snippets.py` runs every PHP snippet in the catalog against the
local toolkit and captures stdout:

```sh
composer install
bin/run-snippets.py --update     # regenerates bin/_expected_outputs.json
bin/run-snippets.py --check      # CI mode: verify outputs match committed JSON
```

The runner rewrites each snippet's
`/wordpress/wp-content/php-toolkit/vendor/autoload.php` to the repo's
local `vendor/autoload.php` and injects a tiny `parse_blocks()` polyfill
so WordPress-specific helpers don't break local runs. Outputs go through
a small normalizer that strips temp-file paths, OIDs, and random nonces
so the JSON is stable across runs.

`bin/build-docs.py` reads the JSON and emits a `<script
type="text/expected-output">` child inside any `<php-snippet>` that has
a captured output. The component then renders that text directly on
first Run.

## Coverage today

80 of the catalog's 84 PHP snippets pre-render. The four that don't are
`HttpClient` / `HttpServer` examples that need real network or a
listening port — those still boot Playground at click time, same as
before.

## Stacked PR

A follow-up PR adds a CI workflow that runs `bin/run-snippets.py
--check` on every push, so we catch drift the moment a snippet's output
changes.
@adamziel adamziel merged commit 97b2d65 into trunk May 2, 2026
28 of 29 checks passed
@adamziel adamziel deleted the adamziel/gh-pages-demos branch May 2, 2026 00:54
adamziel added a commit that referenced this pull request May 3, 2026
## Summary

The runnable docs site at https://wordpress.github.io/php-toolkit/
shipped in #244 and the markdown sources behind it landed in #254. This
PR makes it easy to find from every place a reader is likely to land.

## What changed

**`github.com/WordPress/php-toolkit`** — Repo description and homepage
URL are set via API to `https://wordpress.github.io/php-toolkit/`, so
the sidebar on the repo page surfaces the docs link.

**Root `README.md`** — A "📚 Live, runnable docs" callout sits at the
top, a per-component table replaces the bullet list (each row links to
both the README and the matching reference page on the live site), and a
"Building the docs site" subsection in the dev workflow points at
`bin/build-docs-bundle.sh` + `bin/serve-docs.py`.

**`components/<Name>/README.md`** — All 18 component READMEs gain an
idempotent banner immediately under the H1, deep-linking to that
component's reference page. The banner is wrapped in HTML-comment
markers so future URL/wording updates can be re-applied with one script:

```html
<!-- docs-site-banner -->
> 📚 **Runnable examples:** [https://wordpress.github.io/php-toolkit/reference/zip.html](...)
> Open the page to edit each snippet in your browser and run it in WordPress Playground.
<!-- /docs-site-banner -->
```

**`components/<Name>/composer.json`** — Each per-component package (17
of them; `ToolkitCodingStandards` has no composer.json) gains:

- `homepage` → the matching reference page
- `support: { issues, source, docs }` → links visible on Packagist
- shared `keywords: ["wordpress", "php-toolkit"]`

The result: someone who lands on
https://packagist.org/packages/wp-php-toolkit/zip sees a "Homepage" link
to the runnable docs and a "Documentation" link in the support sidebar.

**Root `composer.json`** — The `wp-php-toolkit/php-toolkit` meta-package
gets the same homepage + support block, plus a description that names
the docs URL ("Browse runnable examples at
https://wordpress.github.io/php-toolkit/").

**`examples/create-wp-site/README.md`** — Same docs-site banner under
the H1 so readers in the examples folder don't miss the docs site.

**`AGENTS.md`** — A `Docs site:` pointer added next to the
upstream/branch lines, with a one-liner that
`bin/_docs_components/<slug>.md` is where the runnable examples live.

## Test plan

- [ ] CI passes (no code changes; 87/87 snippets still match).
- [ ] After merge, https://github.com/WordPress/php-toolkit shows the
homepage URL on the right sidebar.
- [ ] After Packagist re-sync (auto on next release, or manual via the
package page), each `wp-php-toolkit/*` page surfaces the docs URL under
"Homepage" and "Documentation".
- [ ] Component READMEs render the banner cleanly on github.com
(HTML-comment markers stay invisible).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant