From c22e2943bffff4185c09b593ddd4c7ec0ce75647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zieli=C5=84ski?= Date: Fri, 4 Sep 2026 12:30:31 +0200 Subject: [PATCH 1/4] Document runnable code examples in DocBlocks --- index.md | 1 + inline-documentation-standards/php.md | 2 + .../runnable-examples.md | 107 ++++++++++++++++++ manifest.json | 6 + 4 files changed, 116 insertions(+) create mode 100644 inline-documentation-standards/runnable-examples.md diff --git a/index.md b/index.md index d7c7e94..5613358 100644 --- a/index.md +++ b/index.md @@ -15,6 +15,7 @@ WordPress is a big project with thousands of contributors. It's important that b diff --git a/inline-documentation-standards/php.md b/inline-documentation-standards/php.md index 5096c94..ef1e3f3 100644 --- a/inline-documentation-standards/php.md +++ b/inline-documentation-standards/php.md @@ -133,6 +133,8 @@ HTML markup should never be used outside of code examples, though Markdown can b * @link https://core.trac.wordpress.org/ticket/20000 ``` +For guidance on making a PHP example runnable in the Code Reference, see [Runnable code examples in DocBlocks](https://developer.wordpress.org/coding-standards/inline-documentation-standards/runnable-examples/). + #### `@since` Section (Changelogs) Every function, hook, class, and method should have a corresponding `@since` version associated with it (more on that below). diff --git a/inline-documentation-standards/runnable-examples.md b/inline-documentation-standards/runnable-examples.md new file mode 100644 index 0000000..ea2c0fe --- /dev/null +++ b/inline-documentation-standards/runnable-examples.md @@ -0,0 +1,107 @@ +# Runnable code examples in DocBlocks + +A DocBlock example can be marked as runnable. The Code Reference then shows it with a **Run** button, and readers execute and edit it in the browser through [WordPress Playground](https://developer.wordpress.org/playground/handbook/guides/php-code-snippets/). + +This is opt-in. Existing indented examples keep working. Convert an example only when running it teaches something reading it does not. + +## Example +````php +/** + * Generator for a foreach loop to step through each class name for the matched tag. + * + * ```php interactive + * $p = new WP_HTML_Tag_Processor( "
" ); + * $p->next_tag(); + * foreach ( $p->class_list() as $class_name ) { + * echo "{$class_name} "; + * } + * // Outputs: free lang-en + * ``` + */ +```` + +Three parts: a fenced block, the info string `php interactive`, and a trailing `// Outputs:` comment. + +## The fence + +- `php interactive`, lowercase, in that order. Anything else (`PHP interactive`, `php-interactive`, `php title="x" interactive`) renders as plain code. +- May be indented, including inside a list item. Code lines need not match the fence indentation. +- Rendered in place, between the surrounding paragraphs. + +## The code + +Start with the first meaningful line. Do not include `' ); +// Outputs: +``` + +Several lines — empty `// Outputs:` starts a block, each `//` line is one output line, a final empty `//` keeps a trailing newline: +```php +print_r( array( 'fruit' => 'apple' ) ); +// Outputs: +// Array +// ( +// [fruit] => apple +// ) +// +``` + +JSON-encoded — for trailing spaces, tabs, or repeated newlines. Must be one JSON string: +```php +echo "done "; +// Outputs (JSON-encoded): "done " +``` + +Only a trailing standalone line comment counts. `// Outputs:` inside a string, a block comment, after code on the same line, or followed by more code is treated as code. The older ` ```expected-output ` fence still parses; do not use both. + +## Hidden setup + +If the example needs a helper function, a post, or an option, put that in a setup Blueprint ([Playground Blueprint](https://developer.wordpress.org/playground/blueprints/) JSON). It runs first and never appears on the page. + +Inline, directly before or after the PHP fence: +````arduino +```setup-blueprint +{ "steps": [ { "step": "writeFile", "path": "/wordpress/wp-content/mu-plugins/docs-fixture.php", "data": "`. A named Blueprint in the file-level DocBlock is available to every example in the file: +````go +```setup-blueprint shared-greeting +{ "steps": [ ... ] } +``` +```php interactive setup-blueprint=shared-greeting +echo docs_shared_greeting( 'first' ); +// Outputs: Hello, first +``` +```` + +Names are case-sensitive. `blueprint=` and `setupblueprint=` are not recognized. + +## Before you commit + +- Fence reads exactly `php interactive`. +- No `` on any HTML page per the [Playground guide](https://developer.wordpress.org/playground/handbook/guides/php-code-snippets/). + +## Timing and feedback + +The Code Reference is built from the current stable release, so an example in `trunk` appears when that release ships. + +Questions: `#live-doc-snippets` on Make WordPress Slack. Parser bugs: [phpdoc-parser](https://github.com/WordPress/phpdoc-parser/issues). Rendering bugs: [wporg-developer](https://github.com/WordPress/wporg-developer/issues). diff --git a/manifest.json b/manifest.json index 0fe8c6d..f6e7ae9 100644 --- a/manifest.json +++ b/manifest.json @@ -61,6 +61,12 @@ "parent": "inline-documentation-standards", "markdown_source": "https://github.com/WordPress/wpcs-docs/blob/master/inline-documentation-standards/php.md" }, + "inline-documentation-standards/runnable-examples": { + "title": "Runnable code examples in DocBlocks", + "slug": "runnable-examples", + "parent": "inline-documentation-standards", + "markdown_source": "https://github.com/WordPress/wpcs-docs/blob/master/inline-documentation-standards/runnable-examples.md" + }, "changelog": { "title": "Changelog", "slug": "changelog", From 12ad33b9625f87dd139a5ff983082487a8c2dc69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zieli=C5=84ski?= Date: Fri, 4 Sep 2026 12:47:16 +0200 Subject: [PATCH 2/4] Use empty language for nested Markdown examples --- inline-documentation-standards/runnable-examples.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inline-documentation-standards/runnable-examples.md b/inline-documentation-standards/runnable-examples.md index ea2c0fe..2daab12 100644 --- a/inline-documentation-standards/runnable-examples.md +++ b/inline-documentation-standards/runnable-examples.md @@ -68,7 +68,7 @@ Only a trailing standalone line comment counts. `// Outputs:` inside a string, a If the example needs a helper function, a post, or an option, put that in a setup Blueprint ([Playground Blueprint](https://developer.wordpress.org/playground/blueprints/) JSON). It runs first and never appears on the page. Inline, directly before or after the PHP fence: -````arduino +```` ```setup-blueprint { "steps": [ { "step": "writeFile", "path": "/wordpress/wp-content/mu-plugins/docs-fixture.php", "data": "`. A named Blueprint in the file-level DocBlock is available to every example in the file: -````go +```` ```setup-blueprint shared-greeting { "steps": [ ... ] } ``` From f9abd745fb2fcd7b42961b8966afc700f8c43502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zieli=C5=84ski?= Date: Fri, 4 Sep 2026 12:49:10 +0200 Subject: [PATCH 3/4] Place runnable examples in PHP documentation --- index.md | 1 - inline-documentation-standards/php.md | 108 +++++++++++++++++- .../runnable-examples.md | 107 ----------------- manifest.json | 6 - 4 files changed, 107 insertions(+), 115 deletions(-) delete mode 100644 inline-documentation-standards/runnable-examples.md diff --git a/index.md b/index.md index 5613358..d7c7e94 100644 --- a/index.md +++ b/index.md @@ -15,7 +15,6 @@ WordPress is a big project with thousands of contributors. It's important that b diff --git a/inline-documentation-standards/php.md b/inline-documentation-standards/php.md index ef1e3f3..da654db 100644 --- a/inline-documentation-standards/php.md +++ b/inline-documentation-standards/php.md @@ -133,7 +133,113 @@ HTML markup should never be used outside of code examples, though Markdown can b * @link https://core.trac.wordpress.org/ticket/20000 ``` -For guidance on making a PHP example runnable in the Code Reference, see [Runnable code examples in DocBlocks](https://developer.wordpress.org/coding-standards/inline-documentation-standards/runnable-examples/). +#### Runnable examples + +A DocBlock example can be marked as runnable. The Code Reference then shows it with a **Run** button, and readers execute and edit it in the browser through [WordPress Playground](https://developer.wordpress.org/playground/handbook/guides/php-code-snippets/). + +This is opt-in. Existing indented examples keep working. Convert an example only when running it teaches something reading it does not. + +##### Example +````php +/** + * Generator for a foreach loop to step through each class name for the matched tag. + * + * ```php interactive + * $p = new WP_HTML_Tag_Processor( "
" ); + * $p->next_tag(); + * foreach ( $p->class_list() as $class_name ) { + * echo "{$class_name} "; + * } + * // Outputs: free lang-en + * ``` + */ +```` + +Three parts: a fenced block, the info string `php interactive`, and a trailing `// Outputs:` comment. + +##### The fence + +- `php interactive`, lowercase, in that order. Anything else (`PHP interactive`, `php-interactive`, `php title="x" interactive`) renders as plain code. +- May be indented, including inside a list item. Code lines need not match the fence indentation. +- Rendered in place, between the surrounding paragraphs. + +##### The code + +Start with the first meaningful line. Do not include `' ); +// Outputs: +``` + +Several lines — empty `// Outputs:` starts a block, each `//` line is one output line, a final empty `//` keeps a trailing newline: +```php +print_r( array( 'fruit' => 'apple' ) ); +// Outputs: +// Array +// ( +// [fruit] => apple +// ) +// +``` + +JSON-encoded — for trailing spaces, tabs, or repeated newlines. Must be one JSON string: +```php +echo "done "; +// Outputs (JSON-encoded): "done " +``` + +Only a trailing standalone line comment counts. `// Outputs:` inside a string, a block comment, after code on the same line, or followed by more code is treated as code. The older ` ```expected-output ` fence still parses; do not use both. + +##### Hidden setup + +If the example needs a helper function, a post, or an option, put that in a setup Blueprint ([Playground Blueprint](https://developer.wordpress.org/playground/blueprints/) JSON). It runs first and never appears on the page. + +Inline, directly before or after the PHP fence: +```` +```setup-blueprint +{ "steps": [ { "step": "writeFile", "path": "/wordpress/wp-content/mu-plugins/docs-fixture.php", "data": "`. A named Blueprint in the file-level DocBlock is available to every example in the file: +```` +```setup-blueprint shared-greeting +{ "steps": [ ... ] } +``` +```php interactive setup-blueprint=shared-greeting +echo docs_shared_greeting( 'first' ); +// Outputs: Hello, first +``` +```` + +Names are case-sensitive. `blueprint=` and `setupblueprint=` are not recognized. + +##### Before you commit + +- Fence reads exactly `php interactive`. +- No `` on any HTML page per the [Playground guide](https://developer.wordpress.org/playground/handbook/guides/php-code-snippets/). + +##### Timing and feedback + +The Code Reference is built from the current stable release, so an example in `trunk` appears when that release ships. + +Questions: `#live-doc-snippets` on Make WordPress Slack. Parser bugs: [phpdoc-parser](https://github.com/WordPress/phpdoc-parser/issues). Rendering bugs: [wporg-developer](https://github.com/WordPress/wporg-developer/issues). #### `@since` Section (Changelogs) diff --git a/inline-documentation-standards/runnable-examples.md b/inline-documentation-standards/runnable-examples.md deleted file mode 100644 index 2daab12..0000000 --- a/inline-documentation-standards/runnable-examples.md +++ /dev/null @@ -1,107 +0,0 @@ -# Runnable code examples in DocBlocks - -A DocBlock example can be marked as runnable. The Code Reference then shows it with a **Run** button, and readers execute and edit it in the browser through [WordPress Playground](https://developer.wordpress.org/playground/handbook/guides/php-code-snippets/). - -This is opt-in. Existing indented examples keep working. Convert an example only when running it teaches something reading it does not. - -## Example -````php -/** - * Generator for a foreach loop to step through each class name for the matched tag. - * - * ```php interactive - * $p = new WP_HTML_Tag_Processor( "
" ); - * $p->next_tag(); - * foreach ( $p->class_list() as $class_name ) { - * echo "{$class_name} "; - * } - * // Outputs: free lang-en - * ``` - */ -```` - -Three parts: a fenced block, the info string `php interactive`, and a trailing `// Outputs:` comment. - -## The fence - -- `php interactive`, lowercase, in that order. Anything else (`PHP interactive`, `php-interactive`, `php title="x" interactive`) renders as plain code. -- May be indented, including inside a list item. Code lines need not match the fence indentation. -- Rendered in place, between the surrounding paragraphs. - -## The code - -Start with the first meaningful line. Do not include `' ); -// Outputs: -``` - -Several lines — empty `// Outputs:` starts a block, each `//` line is one output line, a final empty `//` keeps a trailing newline: -```php -print_r( array( 'fruit' => 'apple' ) ); -// Outputs: -// Array -// ( -// [fruit] => apple -// ) -// -``` - -JSON-encoded — for trailing spaces, tabs, or repeated newlines. Must be one JSON string: -```php -echo "done "; -// Outputs (JSON-encoded): "done " -``` - -Only a trailing standalone line comment counts. `// Outputs:` inside a string, a block comment, after code on the same line, or followed by more code is treated as code. The older ` ```expected-output ` fence still parses; do not use both. - -## Hidden setup - -If the example needs a helper function, a post, or an option, put that in a setup Blueprint ([Playground Blueprint](https://developer.wordpress.org/playground/blueprints/) JSON). It runs first and never appears on the page. - -Inline, directly before or after the PHP fence: -```` -```setup-blueprint -{ "steps": [ { "step": "writeFile", "path": "/wordpress/wp-content/mu-plugins/docs-fixture.php", "data": "`. A named Blueprint in the file-level DocBlock is available to every example in the file: -```` -```setup-blueprint shared-greeting -{ "steps": [ ... ] } -``` -```php interactive setup-blueprint=shared-greeting -echo docs_shared_greeting( 'first' ); -// Outputs: Hello, first -``` -```` - -Names are case-sensitive. `blueprint=` and `setupblueprint=` are not recognized. - -## Before you commit - -- Fence reads exactly `php interactive`. -- No `` on any HTML page per the [Playground guide](https://developer.wordpress.org/playground/handbook/guides/php-code-snippets/). - -## Timing and feedback - -The Code Reference is built from the current stable release, so an example in `trunk` appears when that release ships. - -Questions: `#live-doc-snippets` on Make WordPress Slack. Parser bugs: [phpdoc-parser](https://github.com/WordPress/phpdoc-parser/issues). Rendering bugs: [wporg-developer](https://github.com/WordPress/wporg-developer/issues). diff --git a/manifest.json b/manifest.json index f6e7ae9..0fe8c6d 100644 --- a/manifest.json +++ b/manifest.json @@ -61,12 +61,6 @@ "parent": "inline-documentation-standards", "markdown_source": "https://github.com/WordPress/wpcs-docs/blob/master/inline-documentation-standards/php.md" }, - "inline-documentation-standards/runnable-examples": { - "title": "Runnable code examples in DocBlocks", - "slug": "runnable-examples", - "parent": "inline-documentation-standards", - "markdown_source": "https://github.com/WordPress/wpcs-docs/blob/master/inline-documentation-standards/runnable-examples.md" - }, "changelog": { "title": "Changelog", "slug": "changelog", From 6218131aebb6f440ca7ccf9f7813e7e79cb24e33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zieli=C5=84ski?= Date: Fri, 4 Sep 2026 13:04:24 +0200 Subject: [PATCH 4/4] Separate runnable example heading from code --- inline-documentation-standards/php.md | 1 + 1 file changed, 1 insertion(+) diff --git a/inline-documentation-standards/php.md b/inline-documentation-standards/php.md index da654db..aff10de 100644 --- a/inline-documentation-standards/php.md +++ b/inline-documentation-standards/php.md @@ -140,6 +140,7 @@ A DocBlock example can be marked as runnable. The Code Reference then shows it w This is opt-in. Existing indented examples keep working. Convert an example only when running it teaches something reading it does not. ##### Example + ````php /** * Generator for a foreach loop to step through each class name for the matched tag.