Created
July 22, 2026 10:20
-
-
Save bgrgicak/0cdb0637bc50476daed943ed1b0b22a5 to your computer and use it in GitHub Desktop.
WP Doom Block repo-hosted blueprint mirror for Playground testing
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", | |
| "preferredVersions": { | |
| "php": "8.3", | |
| "wp": "latest" | |
| }, | |
| "features": { | |
| "networking": true | |
| }, | |
| "landingPage": "/doom-block/", | |
| "meta": { | |
| "title": "Try WP Doom Block in Playground", | |
| "author": "Bero / Gil", | |
| "description": "Installs WP Doom Block and loads a page with the block already inserted." | |
| }, | |
| "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\u2019s 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` \u2014 plugin bootstrap and block registration\n- `includes/render.php` \u2014 server-side render helpers\n- `build/` \u2014 block metadata and compiled assets\n- `tests/run.php` \u2014 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