[Website] Embeddable PHP code snippets via <php-snippet> - #3528
Merged
Conversation
Drop one script tag on any page and you can embed runnable PHP — and
the full WordPress runtime — as inline, syntax-highlighted snippets.
Multiple snippets share a single hidden Playground iframe, so a docs
page with five examples downloads the runtime once instead of five
times. The runtime only boots on the first Run click; until then the
page costs nothing more than a few KB of JS.
The bar that appears during boot is the real staged progress drawn
from the live events Playground emits internally, so visitors see the
same captions ("Preparing WordPress", download progress, blueprint
steps) they would in the standalone PHP Playground.
Includes Playwright coverage that exercises the boot-then-reuse path
across three snippets, and a guide page that documents both the new
embed and the standalone PHP Playground at /php-playground.html.
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds an embeddable <php-snippet> web component that lazy-loads a shared WordPress Playground runtime to run and syntax-highlight PHP snippets, plus demo/docs and Playwright E2E coverage.
Changes:
- Introduces
php-code-snippet.jscustom element with shared runtime boot + progress tracking and a small PHP syntax highlighter. - Adds a demo HTML page and Playwright E2E tests validating progress, output, and runtime reuse.
- Documents the embed + standalone PHP Playground and links the guide prominently in the docs sidebar/index.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/playground/website/public/php-code-snippet.js | Implements <php-snippet> component, shared runtime boot/progress, and syntax highlighting. |
| packages/playground/website/public/php-code-snippet-demo.html | Adds a local demo page with three example snippets. |
| packages/playground/website/playwright/e2e/php-code-snippet.spec.ts | Adds E2E tests for rendering, progress/output, and runtime sharing. |
| packages/docs/site/sidebars.js | Adds the new guide to the Guides sidebar. |
| packages/docs/site/docs/main/guides/php-code-snippets.md | Documents embedding via <php-snippet> and the standalone PHP Playground. |
| packages/docs/site/docs/main/guides/index.md | Links to the new guide at the top of the Guides index. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
adamziel
marked this pull request as draft
April 25, 2026 00:14
Three things came back from the review and they were all fair:
The shared-runtime cache used a single global slot. If two snippets on
the same page asked for different {origin, php, wp} combinations, the
key bookkeeping could get crossed and a snippet might receive the wrong
runtime — or its progress events would leak across boots. Replaced the
single slot with a Map keyed by the runtime triple, with each entry
carrying its own tracker, subscribers, and client. One runtime per
unique combination, no cross-talk.
When a snippet loads its code via the src attribute, a 4xx/5xx response
was treated as snippet code (usually an HTML error page). Now it throws
with status, statusText, and the URL so the failure shows up clearly in
the output panel.
Render used innerHTML += on the shadow root, which serializes and
reparses the previous content. Switched to building the markup in a
template and appending the document fragment, so the style node and any
existing handlers stay intact. Added aria-live="polite" and
aria-atomic="true" on the progress region so screen readers announce
caption and percent updates.
The progress-event dispatch was using a `const self = this` alias that tripped no-this-alias. The lazy getters were carry-over habit from the upstream ProgressTracker — for a one-shot CustomEvent the values at dispatch time are what subscribers see anyway, so the detail object reads them directly off `this` instead. While in there, fixed a related leak Copilot hinted at: if the runtime boot threw, the entry sat in the cache with a rejected promise and every subsequent Run would re-await the same rejection forever. The entry now drops itself on failure, so the next Run gets a fresh attempt.
4 tasks
Collaborator
Author
|
@fellyph this adds a docusaurus doc page – is there a https://wordpress.org/ URL where I should also add it? |
Clarified the comparison between Standalone PHP Playground and <php-snippet> in the documentation.
adamziel
marked this pull request as ready for review
April 27, 2026 14:25
adamziel
added a commit
that referenced
this pull request
Apr 27, 2026
Stacked on #3528. Two changes for the `<php-snippet>` web component: ## 1. Editable snippets Add `editable` to make a snippet a tiny inline playground. Visitors type into a transparent textarea overlaid on the highlighted code; syntax colors update as they go; Run executes whatever's currently in the textarea. ```html <php-snippet name="scratch.php" editable> <script type="application/x-php"> <?php $nums = range(1, 10); echo "Sum: " . array_sum($nums); </script> </php-snippet> ``` No CodeMirror, no Monaco, no extra dependency — ~50 lines added to the component, opt-in. Tab inserts a tab character so it actually feels like an editor. Edits live only in the page; refresh resets to the initial code. ## 2. Better PHP tokenizer The regex highlighter previously bailed on heredoc/nowdoc and didn't know about backticks or PHP 8 attributes. Now it handles: - **Backtick** shell-exec strings (``` `…` ```) — same escape rules as `"…"`. - **Heredoc** (`<<<EOT … EOT;`) and **nowdoc** (`<<<'EOT' … EOT;`), including PHP 7.3+ indented closers. - **`#[Attribute]`** (PHP 8) — no longer eaten as a `#` line comment. - Single, double, and backtick quotes share one `scanQuoted` helper that correctly skips `\\`, `\"`, `\'`, etc., and tolerates unterminated strings without overshooting. ## Try it Run `npm run dev` and open http://127.0.0.1:5400/website-server/php-code-snippet-demo.html — the demo includes an editable snippet and a snippet exercising heredoc/backticks/attributes. ## Test plan - [ ] CI passes including the new editable-runs-typed-code Playwright test. - [ ] In the demo page, type into the editable snippet, see colors update, click Run, see your output. - [ ] Confirm the three non-editable snippets render unchanged. - [ ] Snippets containing heredoc, backticks, or `#[Attribute]` highlight correctly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a runnable PHP code snippet web component:
CleanShot.2026-04-25.at.17.45.39.mp4
Here's how to use it:
The script is around 5 KB gzipped and contains no PHP or WordPress — those are downloaded only on the first Run click. Multiple snippets on the same page share a single hidden Playground iframe, so a docs page with five examples pays the runtime cost once instead of five times.
There is no code editor shipped with this PR, just a tiny tokenizer/syntax highlighter.
The progress bar that shows up during boot is the real staged progress drawn from the live events Playground emits internally, so visitors see the same captions ("Preparing WordPress", download progress, blueprint steps) they'd see in the standalone PHP Playground at
/php-playground.html.Try it
Run
npm run devand open http://127.0.0.1:5400/website-server/php-code-snippet-demo.html. Three snippets, one shared runtime — open the Network tab and watch the second and third Run clicks reuse what the first one downloaded.What's in here
<php-snippet>web component (packages/playground/website/public/php-code-snippet.js) and a demo page next to it.test-e2e-playwrightCI job./guides/php-code-snippets) that documents both the embed and the standalone PHP Playground at/php-playground.html— the latter previously had no docs at all. Linked prominently from the Guides index.Notes for reviewers
The component duck-types a
ProgressTrackerso it can subscribe to staged progress events. The published/client/index.jsdoesn't export the realProgressTrackerclass today; once it does, the inline copy can be replaced with animport. Worth a small follow-up.Test plan
test-e2e-playwright(Chromium / Firefox / WebKit) passes the three new tests./guides/php-code-snippetsin the docs site, verify the page renders and the sidebar entry sits at the top of Guides.