diff --git a/README.md b/README.md index 5aa5dbc4..70c3471b 100644 --- a/README.md +++ b/README.md @@ -85,13 +85,14 @@ See the [Underscores website](https://underscores.me/) for more details. Generates PHP, JS and CSS code for registering a Gutenberg block for a plugin or theme. ~~~ -wp scaffold block [--title=] [--dashicon=<dashicon>] [--category=<category>] [--textdomain=<textdomain>] [--theme] [--plugin=<plugin>] [--force] +wp scaffold block <slug> [--title=<title>] [--dashicon=<dashicon>] [--category=<category>] [--theme] [--plugin=<plugin>] [--force] ~~~ Blocks are the fundamental element of the Gutenberg editor. They are the primary way in which plugins and themes can register their own functionality and extend the capabilities of the editor. -Visit https://wordpress.org/gutenberg/handbook/block-api/ to learn more about Block API. -When you scaffold a block you must use either the theme or plugin option. +Visit the [Gutenberg handbook](https://wordpress.org/gutenberg/handbook/block-api/) to learn more about Block API. + +When you scaffold a block you must use either the theme or plugin option. The latter is recommended. **OPTIONS** @@ -113,11 +114,8 @@ When you scaffold a block you must use either the theme or plugin option. - embed - formatting - layout - - reusable-blocks - widgets - - [--textdomain=<textdomain>] - The textdomain to use for the labels. + --- [--theme] Create files in the active theme directory. Specify a theme with `--theme=<theme>` to have the file placed in that theme. @@ -130,14 +128,14 @@ When you scaffold a block you must use either the theme or plugin option. **EXAMPLES** - # Generate a 'movie' block for the 'simple-life' theme - $ wp scaffold block movie --title="Movie block" --theme=simple-life - Success: Created block 'Movie block'. - # Generate a 'movie' block for the 'movies' plugin $ wp scaffold block movie --title="Movie block" --plugin=movies Success: Created block 'Movie block'. - + + # Generate a 'movie' block for the 'simple-life' theme + $ wp scaffold block movie --title="Movie block" --theme=simple-life + Success: Created block 'Movie block'. + # Create a new plugin and add two blocks # Create plugin called books $ wp scaffold plugin books @@ -146,6 +144,8 @@ When you scaffold a block you must use either the theme or plugin option. # Add a second block to plugin called books. $ wp scaffold block books --title="Book List" --plugin=books + + ### wp scaffold child-theme Generates child theme based on an existing theme. diff --git a/features/scaffold-block.feature b/features/scaffold-block.feature index a8d35c63..d7bceb2c 100644 --- a/features/scaffold-block.feature +++ b/features/scaffold-block.feature @@ -50,14 +50,22 @@ Feature: WordPress block code scaffolding """ add_action( 'enqueue_block_editor_assets', 'the_green_mile_enqueue_block_editor_assets' ); """ + And the {PLUGIN_DIR}/blocks/the-green-mile.php file should contain: + """ + $style_css = 'the-green-mile/style.css'; + """ + And the {PLUGIN_DIR}/blocks/the-green-mile.php file should contain: + """ + add_action( 'enqueue_block_assets', 'the_green_mile_enqueue_block_assets' ); + """ And the {PLUGIN_DIR}/blocks/the-green-mile/block.js file should exist And the {PLUGIN_DIR}/blocks/the-green-mile/block.js file should contain: """ - wp.blocks.registerBlockType( 'movies/the-green-mile', { + registerBlockType( 'movies/the-green-mile', { """ And the {PLUGIN_DIR}/blocks/the-green-mile/block.js file should contain: """ - title: __( 'The green mile', 'movies' ), + title: __( 'The green mile' ), """ And the {PLUGIN_DIR}/blocks/the-green-mile/block.js file should contain: """ @@ -65,13 +73,22 @@ Feature: WordPress block code scaffolding """ And the {PLUGIN_DIR}/blocks/the-green-mile/block.js file should contain: """ - __( 'Replace with your content!', 'movies' ) + __( 'Hello from the editor!' ) + """ + And the {PLUGIN_DIR}/blocks/the-green-mile/block.js file should contain: + """ + __( 'Hello from the saved content!' ) """ And the {PLUGIN_DIR}/blocks/the-green-mile/editor.css file should exist And the {PLUGIN_DIR}/blocks/the-green-mile/editor.css file should contain: """ .wp-block-movies-the-green-mile { """ + And the {PLUGIN_DIR}/blocks/the-green-mile/style.css file should exist + And the {PLUGIN_DIR}/blocks/the-green-mile/style.css file should contain: + """ + .wp-block-movies-the-green-mile { + """ And STDOUT should be: """ Success: Created block 'The green mile'. @@ -81,7 +98,7 @@ Feature: WordPress block code scaffolding When I run `wp scaffold block shawshank-redemption --plugin=movies --title="The Shawshank Redemption"` Then the {PLUGIN_DIR}/blocks/shawshank-redemption/block.js file should contain: """ - title: __( 'The Shawshank Redemption', 'movies' ), + title: __( 'The Shawshank Redemption' ), """ And STDOUT should be: """ @@ -110,22 +127,12 @@ Feature: WordPress block code scaffolding Success: Created block 'Pulp fiction'. """ - Scenario: Scaffold a block with a specific textdomain provided - When I run `wp scaffold block inception --plugin=movies --textdomain=MY-MOVIES` - Then the {PLUGIN_DIR}/blocks/inception/block.js file should contain: - """ - __( 'Replace with your content!', 'MY-MOVIES' ) - """ - And STDOUT should be: - """ - Success: Created block 'Inception'. - """ - Scenario: Scaffold a block for an active theme When I run `wp scaffold block fight-club --theme` Then the {THEME_DIR}/blocks/fight-club.php file should exist And the {THEME_DIR}/blocks/fight-club/block.js file should exist And the {THEME_DIR}/blocks/fight-club/editor.css file should exist + And the {THEME_DIR}/blocks/fight-club/style.css file should exist And STDOUT should be: """ Success: Created block 'Fight club'. @@ -143,6 +150,7 @@ Feature: WordPress block code scaffolding Then the {THEME_DIR}/blocks/intouchables.php file should exist And the {THEME_DIR}/blocks/intouchables/block.js file should exist And the {THEME_DIR}/blocks/intouchables/editor.css file should exist + And the {THEME_DIR}/blocks/intouchables/style.css file should exist And STDOUT should be: """ Success: Created block 'Intouchables'. diff --git a/src/Scaffold_Command.php b/src/Scaffold_Command.php index d67e79cc..0ab09b2b 100644 --- a/src/Scaffold_Command.php +++ b/src/Scaffold_Command.php @@ -204,9 +204,10 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) * Generates PHP, JS and CSS code for registering a Gutenberg block for a plugin or theme. * * Blocks are the fundamental element of the Gutenberg editor. They are the primary way in which plugins and themes can register their own functionality and extend the capabilities of the editor. - * Visit https://wordpress.org/gutenberg/handbook/block-api/ to learn more about Block API. * - * When you scaffold a block you must use either the theme or plugin option. + * Visit the [Gutenberg handbook](https://wordpress.org/gutenberg/handbook/block-api/) to learn more about Block API. + * + * When you scaffold a block you must use either the theme or plugin option. The latter is recommended. * * ## OPTIONS * @@ -228,11 +229,8 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) * - embed * - formatting * - layout - * - reusable-blocks * - widgets - * - * [--textdomain=<textdomain>] - * : The textdomain to use for the labels. + * --- * * [--theme] * : Create files in the active theme directory. Specify a theme with `--theme=<theme>` to have the file placed in that theme. @@ -245,14 +243,14 @@ private function _scaffold( $slug, $assoc_args, $defaults, $subdir, $templates ) * * ## EXAMPLES * - * # Generate a 'movie' block for the 'simple-life' theme - * $ wp scaffold block movie --title="Movie block" --theme=simple-life - * Success: Created block 'Movie block'. - * * # Generate a 'movie' block for the 'movies' plugin * $ wp scaffold block movie --title="Movie block" --plugin=movies * Success: Created block 'Movie block'. * + * # Generate a 'movie' block for the 'simple-life' theme + * $ wp scaffold block movie --title="Movie block" --theme=simple-life + * Success: Created block 'Movie block'. + * * # Create a new plugin and add two blocks * # Create plugin called books * $ wp scaffold plugin books @@ -273,7 +271,6 @@ public function block( $args, $assoc_args ) { $defaults = array( 'title' => str_replace( '-', ' ', $slug ), 'category' => 'widgets', - 'textdomain' => '', ); $data = $this->extract_args( $assoc_args, $defaults ); @@ -292,7 +289,6 @@ public function block( $args, $assoc_args ) { ) ); $data['namespace'] = $control_args['plugin'] ? $control_args['plugin'] : $this->get_theme_name( $control_args['theme'] ); - $data['textdomain'] = $this->get_textdomain( $data['textdomain'], $control_args ); $data['machine_name'] = $this->generate_machine_name( $slug ); $block_dir = $this->get_output_path( $control_args, "/blocks" ); @@ -304,6 +300,7 @@ public function block( $args, $assoc_args ) { "$block_dir/$slug.php" => self::mustache_render( 'block-php.mustache', $data ), "$block_dir/$slug/block.js" => self::mustache_render( 'block-block-js.mustache', $data ), "$block_dir/$slug/editor.css" => self::mustache_render( 'block-editor-css.mustache', $data ), + "$block_dir/$slug/style.css" => self::mustache_render( 'block-style-css.mustache', $data ), ), $control_args['force'] ); $this->log_whether_files_written( $files_written, diff --git a/templates/block-block-js.mustache b/templates/block-block-js.mustache index dcab04b1..72276318 100644 --- a/templates/block-block-js.mustache +++ b/templates/block-block-js.mustache @@ -1,33 +1,81 @@ ( function( wp ) { + /** + * Registers a new block provided a unique name and an object defining its behavior. + * @see https://github.com/WordPress/gutenberg/tree/master/blocks#api + */ + var registerBlockType = wp.blocks.registerBlockType; + /** + * Returns a new element of given type. Element is an abstraction layer atop React. + * @see https://github.com/WordPress/gutenberg/tree/master/element#element + */ var el = wp.element.createElement; + /** + * Retrieves the translation of text. + * @see https://github.com/WordPress/gutenberg/tree/master/i18n#api + */ var __ = wp.i18n.__; - // Visit https://wordpress.org/gutenberg/handbook/block-api/ to learn about Block API - wp.blocks.registerBlockType( '{{namespace}}/{{slug}}', { - title: __( '{{title_ucfirst}}', '{{textdomain}}' ), + /** + * Every block starts by registering a new block type definition. + * @see https://wordpress.org/gutenberg/handbook/block-api/ + */ + registerBlockType( '{{namespace}}/{{slug}}', { + /** + * This is the display title for your block, which can be translated with `i18n` functions. + * The block inserter will show this name. + */ + title: __( '{{title_ucfirst}}' ), {{#dashicon}} + /** + * An icon property should be specified to make it easier to identify a block. + * These can be any of WordPress’ Dashicons, or a custom svg element. + */ icon: '{{dashicon}}', {{/dashicon}} + /** + * Blocks are grouped into categories to help users browse and discover them. + * The categories provided by core are `common`, `embed`, `formatting`, `layout` and `widgets`. + */ category: '{{category}}', - // Remove to make block editable in HTML mode. - supportHTML: false, + /** + * Optional block extended support features. + */ + supports: { + // Removes support for an HTML mode. + html: false, + }, + /** + * The edit function describes the structure of your block in the context of the editor. + * This represents what the editor will render when the block is used. + * @see https://wordpress.org/gutenberg/handbook/block-edit-save/#edit + * + * @param {Object} [props] Properties passed from the editor. + * @return {Element} Element to render. + */ edit: function( props ) { return el( 'p', { className: props.className }, - __( 'Replace with your content!', '{{textdomain}}' ) + __( 'Hello from the editor!' ) ); }, + /** + * The save function defines the way in which the different attributes should be combined + * into the final markup, which is then serialized by Gutenberg into `post_content`. + * @see https://wordpress.org/gutenberg/handbook/block-edit-save/#save + * + * @return {Element} Element to render. + */ save: function() { return el( 'p', {}, - __( 'Replace with your content!', '{{textdomain}}' ) + __( 'Hello from the saved content!' ) ); } } ); diff --git a/templates/block-editor-css.mustache b/templates/block-editor-css.mustache index 4df4f151..fc68223e 100644 --- a/templates/block-editor-css.mustache +++ b/templates/block-editor-css.mustache @@ -1,5 +1,9 @@ +/** + * The following styles get applied inside the editor only. + * + * Replace them with your own styles or remove the file completely. + */ + .wp-block-{{namespace}}-{{slug}} { - /* Replace with your styles. */ - background-color: #000; - color: #fff; + border: 1px dotted #f00; } diff --git a/templates/block-php.mustache b/templates/block-php.mustache index b25e10fd..a8212b8b 100644 --- a/templates/block-php.mustache +++ b/templates/block-php.mustache @@ -1,16 +1,54 @@ <?php +/** + * Functions to register client-side assets (scripts and stylesheets) for the Gutenberg block. + * + * @package {{namespace}} + */ +/** + * Enqueues block assets to apply inside the editor only. + */ function {{machine_name}}_enqueue_block_editor_assets() { $dir = dirname( __FILE__ ); + $block_js = '{{slug}}/block.js'; + wp_enqueue_script( + '{{slug}}-block-editor', + plugins_url( $block_js, __FILE__ ), + array( + 'wp-blocks', + 'wp-i18n', + 'wp-element', + ), + filemtime( "$dir/$block_js" ) + ); + $editor_css = '{{slug}}/editor.css'; - wp_enqueue_script( '{{slug}}-block', plugins_url( $block_js, __FILE__ ), array( - 'wp-blocks', - 'wp-i18n', - 'wp-element', - ), filemtime( "$dir/$block_js" ) ); - wp_enqueue_style( '{{slug}}-block', plugins_url( $editor_css, __FILE__ ), array( - 'wp-blocks', - ), filemtime( "$dir/$editor_css" ) ); + wp_enqueue_style( + '{{slug}}-block-editor', + plugins_url( $editor_css, __FILE__ ), + array( + 'wp-blocks', + ), + filemtime( "$dir/$editor_css" ) + ); } add_action( 'enqueue_block_editor_assets', '{{machine_name}}_enqueue_block_editor_assets' ); + +/** + * Enqueues block assets to apply both on the front of your site and in the editor. + */ +function {{machine_name}}_enqueue_block_assets() { + $dir = dirname( __FILE__ ); + + $style_css = '{{slug}}/style.css'; + wp_enqueue_style( + '{{slug}}-block', + plugins_url( $style_css, __FILE__ ), + array( + 'wp-blocks', + ), + filemtime( "$dir/$style_css" ) + ); +} +add_action( 'enqueue_block_assets', '{{machine_name}}_enqueue_block_assets' ); diff --git a/templates/block-style-css.mustache b/templates/block-style-css.mustache new file mode 100644 index 00000000..9a6f5fc7 --- /dev/null +++ b/templates/block-style-css.mustache @@ -0,0 +1,11 @@ +/** + * The following styles get applied both on the front of your site and in the editor. + * + * Replace them with your own styles or remove the file completely. + */ + +.wp-block-{{namespace}}-{{slug}} { + background-color: #000; + color: #fff; + padding: 2px; +}