Created
July 22, 2026 10:11
-
-
Save bgrgicak/45bf1a8ad1195243ee53316857c7a0e5 to your computer and use it in GitHub Desktop.
WP Doom Block Playground blueprint
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
| { | |
| "$schema": "https://playground.wordpress.net/blueprint-schema.json", | |
| "meta": { | |
| "title": "WP Doom Block demo", | |
| "author": "Bero / Gil", | |
| "description": "Installs the WP Doom Block plugin and creates a page with the DOOM block already inserted." | |
| }, | |
| "landingPage": "/doom-block/", | |
| "preferredVersions": { | |
| "php": "8.3", | |
| "wp": "latest" | |
| }, | |
| "features": { | |
| "networking": true | |
| }, | |
| "steps": [ | |
| { | |
| "step": "installPlugin", | |
| "pluginData": { | |
| "resource": "literal:directory", | |
| "name": "wp-doom-block", | |
| "files": { | |
| "wp-doom-block.php": "<?php\n/**\n * Plugin Name: WP Doom Block\n * Description: Adds a Gutenberg block that embeds playable Doom in a post or page.\n * Version: 0.1.0\n * Requires at least: 6.5\n * Requires PHP: 8.0\n * Author: Gil / Hermes\n * License: GPL-2.0-or-later\n * License URI: https://www.gnu.org/licenses/gpl-2.0.html\n * Text Domain: wp-doom-block\n *\n * @package WPDoomBlock\n */\n\ndeclare(strict_types=1);\n\nif (! defined('ABSPATH')) {\n exit;\n}\n\nrequire_once __DIR__ . '/includes/render.php';\n\nfunction wp_doom_block_register(): void {\n $dir = __DIR__ . '/build';\n\n register_block_type(\n $dir,\n [\n 'render_callback' => 'wp_doom_block_render',\n ]\n );\n}\nadd_action('init', 'wp_doom_block_register');\n", | |
| "README.md": "# WP Doom Block\n\nA WordPress plugin that adds a Gutenberg block for embedding playable DOOM in a post or page.\n\n## Inspiration\n\nThis block was inspired by Rhys Wynne’s work on bringing DOOM into WordPress and WordPress Playground.\n\n- Author: Rhys Wynne\n- Blog post: [Can WordPress run Doom? (of course it can, here's how)](https://dwinrhys.com/2024/05/08/can-wordpress-run-doom-of-course-it-can-heres-how/)\n- Related original plugin/repo: [rhyswynne/wpdoom](https://github.com/rhyswynne/wpdoom)\n\nThis plugin is a separate Gutenberg block implementation and does not reuse the original shortcode-based plugin architecture.\n\n## What this plugin does\n\n- Registers a Gutenberg block named `create-block/wp-doom-block`\n- Renders a start button that lazy-loads a DOOM iframe on the front end\n- Lets the editor configure the game URL, frame height, and button text\n\n## Local structure\n\n- `wp-doom-block.php` — plugin bootstrap and block registration\n- `includes/render.php` — server-side render helpers\n- `build/` — block metadata and compiled assets\n- `tests/run.php` — lightweight verification script\n\n## Verification\n\nRun:\n\n```bash\nphp tests/run.php\n```\n\nExpected output:\n\n```text\nAll tests passed\n```\n", | |
| "includes": { | |
| "render.php": "<?php\n\ndeclare(strict_types=1);\n\nfunction wp_doom_block_escape_url(string $value): string {\n return function_exists('esc_url') ? esc_url($value) : htmlspecialchars($value, ENT_QUOTES, 'UTF-8');\n}\n\nfunction wp_doom_block_escape_attr(string $value): string {\n return function_exists('esc_attr') ? esc_attr($value) : htmlspecialchars($value, ENT_QUOTES, 'UTF-8');\n}\n\nfunction wp_doom_block_escape_html(string $value): string {\n return function_exists('esc_html') ? esc_html($value) : htmlspecialchars($value, ENT_QUOTES, 'UTF-8');\n}\n\nfunction wp_doom_block_render_markup(array $attributes, string $wrapperAttributes = ''): string {\n $defaults = [\n 'gameUrl' => 'https://js-dos.com/games/doom.exe.html',\n 'height' => 600,\n 'startButtonText' => 'Click to play DOOM',\n ];\n\n $attributes = array_merge($defaults, $attributes);\n\n $height = is_numeric($attributes['height']) ? max(240, (int) $attributes['height']) : 600;\n $gameUrl = wp_doom_block_escape_url((string) $attributes['gameUrl']);\n $buttonText = wp_doom_block_escape_html((string) $attributes['startButtonText']);\n\n $wrapperAttributes = trim($wrapperAttributes);\n if ($wrapperAttributes === '') {\n $wrapperAttributes = 'class=\"wp-block-create-block-wp-doom-block wp-doom-block\"';\n }\n\n return sprintf(\n '<div %1$s data-game-url=\"%2$s\">'\n . '<div class=\"wp-doom-block__shell\" style=\"min-height:%3$dpx\">'\n . '<button type=\"button\" class=\"wp-doom-block__start-button\" data-doom-start>%4$s</button>'\n . '<iframe class=\"wp-doom-block__iframe\" title=\"DOOM\" loading=\"lazy\" allowfullscreen data-doom-frame data-src=\"%2$s\" style=\"height:%3$dpx\" hidden></iframe>'\n . '</div>'\n . '</div>',\n $wrapperAttributes,\n $gameUrl,\n $height,\n $buttonText\n );\n}\n\nfunction wp_doom_block_render(array $attributes, string $content = '', $block = null): string {\n $wrapperAttributes = function_exists('get_block_wrapper_attributes')\n ? get_block_wrapper_attributes([\n 'class' => 'wp-doom-block',\n ])\n : 'class=\"wp-block-create-block-wp-doom-block wp-doom-block\"';\n\n return wp_doom_block_render_markup($attributes, $wrapperAttributes);\n}\n" | |
| }, | |
| "build": { | |
| "block.json": "{\n \"$schema\": \"https://schemas.wp.org/trunk/block.json\",\n \"apiVersion\": 3,\n \"name\": \"create-block/wp-doom-block\",\n \"version\": \"0.1.0\",\n \"title\": \"DOOM\",\n \"category\": \"widgets\",\n \"icon\": \"games\",\n \"description\": \"Embed playable DOOM in a post or page.\",\n \"keywords\": [\"doom\", \"game\", \"retro\", \"embed\"],\n \"textdomain\": \"wp-doom-block\",\n \"attributes\": {\n \"gameUrl\": {\n \"type\": \"string\",\n \"default\": \"https://js-dos.com/games/doom.exe.html\"\n },\n \"height\": {\n \"type\": \"number\",\n \"default\": 600\n },\n \"startButtonText\": {\n \"type\": \"string\",\n \"default\": \"Click to play DOOM\"\n }\n },\n \"editorScript\": \"file:./index.js\",\n \"viewScript\": \"file:./view.js\",\n \"style\": \"file:./style.css\"\n}\n", | |
| "index.asset.php": "<?php\nreturn [\n 'dependencies' => [\n 'wp-blocks',\n 'wp-block-editor',\n 'wp-components',\n 'wp-element',\n 'wp-i18n',\n ],\n 'version' => '0.1.0',\n];\n", | |
| "index.js": "( function ( blocks, blockEditor, components, element, i18n ) {\n var el = element.createElement;\n var useBlockProps = blockEditor.useBlockProps;\n var InspectorControls = blockEditor.InspectorControls;\n var PanelBody = components.PanelBody;\n var RangeControl = components.RangeControl;\n var TextControl = components.TextControl;\n var __ = i18n.__;\n\n blocks.registerBlockType( 'create-block/wp-doom-block', {\n edit: function ( props ) {\n var attributes = props.attributes;\n var setAttributes = props.setAttributes;\n var blockProps = useBlockProps( {\n className: 'wp-doom-block-editor',\n } );\n\n return [\n el(\n InspectorControls,\n { key: 'inspector' },\n el(\n PanelBody,\n { title: __( 'DOOM settings', 'wp-doom-block' ), initialOpen: true },\n el( TextControl, {\n label: __( 'Game URL', 'wp-doom-block' ),\n value: attributes.gameUrl || 'https://js-dos.com/games/doom.exe.html',\n onChange: function ( value ) {\n setAttributes( { gameUrl: value } );\n },\n help: __( 'Swap in another js-dos compatible page if you want a different build.', 'wp-doom-block' ),\n } ),\n el( RangeControl, {\n label: __( 'Frame height', 'wp-doom-block' ),\n value: attributes.height || 600,\n onChange: function ( value ) {\n setAttributes( { height: value } );\n },\n min: 240,\n max: 1000,\n } ),\n el( TextControl, {\n label: __( 'Start button text', 'wp-doom-block' ),\n value: attributes.startButtonText || 'Click to play DOOM',\n onChange: function ( value ) {\n setAttributes( { startButtonText: value } );\n },\n } )\n )\n ),\n el(\n 'div',\n Object.assign( { key: 'preview' }, blockProps ),\n el( 'div', { className: 'wp-doom-block__shell', style: { minHeight: ( attributes.height || 600 ) + 'px' } },\n el( 'p', { className: 'wp-doom-block__eyebrow' }, __( 'Playable DOOM block', 'wp-doom-block' ) ),\n el( 'h3', null, 'DOOM' ),\n el( 'p', null, __( 'The front end renders a start button that lazy-loads the game iframe.', 'wp-doom-block' ) ),\n el( 'p', null, __( 'Source:', 'wp-doom-block' ) + ' ' + ( attributes.gameUrl || 'https://js-dos.com/games/doom.exe.html' ) ),\n el( 'button', { type: 'button', className: 'wp-doom-block__start-button', disabled: true }, attributes.startButtonText || 'Click to play DOOM' )\n )\n )\n ];\n },\n save: function () {\n return null;\n },\n } );\n} )( window.wp.blocks, window.wp.blockEditor, window.wp.components, window.wp.element, window.wp.i18n );\n", | |
| "style.css": ".wp-block-create-block-wp-doom-block,\n.wp-doom-block-editor {\n width: 100%;\n}\n\n.wp-doom-block__shell {\n display: flex;\n min-height: 600px;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 1rem;\n padding: 1.5rem;\n border-radius: 16px;\n background: radial-gradient(circle at top, #2f2f2f 0%, #111 58%, #000 100%);\n color: #f7f0d0;\n box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);\n}\n\n.wp-doom-block__eyebrow {\n margin: 0;\n font-size: 0.8rem;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: #ffcc66;\n}\n\n.wp-doom-block__start-button {\n border: 0;\n border-radius: 999px;\n padding: 0.9rem 1.35rem;\n font-weight: 700;\n cursor: pointer;\n background: linear-gradient(180deg, #ff7b2f 0%, #c93c00 100%);\n color: #fff;\n}\n\n.wp-doom-block__start-button[disabled] {\n cursor: default;\n opacity: 1;\n}\n\n.wp-doom-block__iframe {\n width: 100%;\n min-height: 600px;\n border: 0;\n border-radius: 12px;\n background: #000;\n}\n", | |
| "view.asset.php": "<?php\nreturn [\n 'dependencies' => [],\n 'version' => '0.1.0',\n];\n", | |
| "view.js": "document.addEventListener('click', function (event) {\n var button = event.target.closest('[data-doom-start]');\n if (!button) {\n return;\n }\n\n var shell = button.closest('.wp-doom-block__shell');\n if (!shell) {\n return;\n }\n\n var iframe = shell.querySelector('[data-doom-frame]');\n if (!iframe) {\n return;\n }\n\n if (!iframe.getAttribute('src')) {\n iframe.setAttribute('src', iframe.dataset.src || 'https://js-dos.com/games/doom.exe.html');\n }\n\n iframe.hidden = false;\n button.hidden = true;\n} );\n" | |
| } | |
| } | |
| }, | |
| "options": { | |
| "activate": true | |
| }, | |
| "ifAlreadyInstalled": "overwrite" | |
| }, | |
| { | |
| "step": "runPHP", | |
| "code": "<?php\nrequire '/wordpress/wp-load.php';\nupdate_option( 'blogname', 'WP Doom Block Demo' );\nupdate_option( 'blogdescription', 'Playable DOOM inside a Gutenberg block' );\nupdate_option( 'permalink_structure', '/%postname%/' );\n$page_id = wp_insert_post( [\n 'post_title' => 'DOOM Block Demo',\n 'post_name' => 'doom-block',\n 'post_status' => 'publish',\n 'post_type' => 'page',\n 'post_content' => '<!-- wp:create-block/wp-doom-block {\\\"height\\\":600,\\\"startButtonText\\\":\\\"Click to play DOOM\\\"} /-->'\n] );\nif ( is_wp_error( $page_id ) ) {\n throw new Exception( $page_id->get_error_message() );\n}\nupdate_option( 'show_on_front', 'page' );\nupdate_option( 'page_on_front', (int) $page_id );\nflush_rewrite_rules();" | |
| } | |
| ] | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment