From 7a6de9705f78d3dec1deb05430babbfbaf5d3c13 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 6 Feb 2019 12:26:58 +0100 Subject: [PATCH 01/33] Add the block registration RFC --- docs/rfc/block-registration.md | 369 +++++++++++++++++++++++++++++++++ 1 file changed, 369 insertions(+) create mode 100644 docs/rfc/block-registration.md diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md new file mode 100644 index 00000000000000..aba539d1f31c8e --- /dev/null +++ b/docs/rfc/block-registration.md @@ -0,0 +1,369 @@ +This RFC is intended to serve both as a specification and as documentation for the implementation of runtime-agnostic block type registration. + +## Requirements + +Behind any block type registration is some abstract concept of a unit of content. This content type can be described without consideration of any particular technology. In much the same way, we should be able to describe the core constructs of a block type in a way which can be interpreted in any runtime. + +In more practical terms, an implementation should fulfill requirements that... + +* A block type registration should be declarative and context-agnostic. Any runtime (PHP, JS, or other) should be able to interpret the basics of a block type (see "Block API" in the sections below) and should be able to fetch or retrieve the definitions of the context-specific implementation details. The following things should be made possible: + * Building REST APIs to fetch the available block types + * Building REST APIs to fetch block objects from posts +* This API should be backward compatible with what we have at the moment. +* It should be possible to statically analyze a block type in order to support advanced use-cases required by one of the [9 projects](https://make.wordpress.org/core/2018/12/08/9-priorities-for-2019/) for 2019 in Wordpress: "Building a WordPress.org directory for discovering blocks, and a way to seamlessly install them." +* It should not require a build tool compilation step (e.g. Babel, Webpack) to author code which would be referenced in a block type definition. +* There should allow the potential to dynamically load ("lazy-load") block types, or parts of block type definitions. + +## References + +* Issue: [Block API: Server-side awareness of block types](https://github.com/WordPress/gutenberg/issues/2751) +* Follow-up issue: [Expose available blocks via an API](https://github.com/WordPress/gutenberg/issues/4116) +* Current documentation: [https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/](https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/) + + +## Previous attempts + +Initial support for server-defined block attributes was merged as part of [#2529](https://github.com/WordPress/gutenberg/pull/2529). PHP block type registrations are merged with those defined in the JavaScript runtime. While this enabled blocks to be defined within PHP, the majority of block types continue to be defined within JavaScript alone. The support was reserved for the exclusive use of [dynamic block types](https://wordpress.org/gutenberg/handbook/designers-developers/developers/tutorials/block-tutorial/creating-dynamic-blocks/), in large part because [edit and save behaviors](https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-edit-save/) must still be implemented in JavaScript, and because a solution hadn't been considered for how to create individual block bundles during the build process, nor how to load such bundles efficiently if it were to come to be implemented. + +A demonstration for how block registration could be made filterable in PHP was explored in [#5802](https://github.com/WordPress/gutenberg/pull/5802). The purpose here was to explore how plugins could have better control over the registration. + +Another exploration in [#5652](https://github.com/WordPress/gutenberg/pull/5652) considered using JSON as a file format to share block type definitions between JavaScript and PHP. + +### Conclusions + +* The current approaches to client-side block type registration cannot support the proposed requirement to have all block types known outside the browser context. +* Using a statically-defined, JSON-formatted block type definition enables easy integration in both JavaScript and PHP runtimes. +* Registering a block type in PHP would allow for attribute default values to be assigned as dynamically generated from some external state (e.g. a database value, or localized string). +* By default, JSON does not support localization or dynamic values. +* On the server, a block type `icon` property can only be assigned as a string and thus cannot support SVGs and component-based icons. + +--- + +# Block Type Registration RFC + +## Introduction + +Blocks are the fundamental elements of the editor. They are the primary way in which plugins and themes can register their own functionality and extend the capabilities of the editor. + +## Registering a block type + +To register a new block type, start by creating a `block.json` file. This file: + +* Gives a name to the block type. +* Defines some important metadata about the registered block type (title, category, icon, description, keywords). +* Defines the attributes of your block type. +* Links to the editor implementation of your block type, the save function and any other context-aware property. + +**Example:** + + +```json +{ + "name": "my-plugin/notice", + "title": "Notice", + "category": "common", + "icon": "star", + "description": "Shows warning, error or success notices ...", + "keywords": [ "alert", "message" ], + "attributes": { /* Block attributes definition */ }, + "edit": "blocks/notice-edit.js", + "save": "blocks/notice-save.js", +} +``` + +## Block API + +This section describes all the properties that can be added to the `block.json` file to define the behavior and metadata of block types. + +### Name + +* Type: string +* Required +* Localized: No +* Property: `name` + +```json +{ "name": "core/heading" } +``` + +The name for a block is a unique string that identifies a block. Names have to be structured as `namespace/block-name`, where namespace is the name of your plugin or theme. + +**Note:** A block name can only contain lowercase alphanumeric characters, dashes, and at most one forward slash to designate the plugin-unique namespace prefix. It must begin with a letter. + +**Note:** This name is used on the comment delimiters as ``. Block types in the `core` namespace do not include a namespace when serialized. + +**Important Note:** + +Other block properties that point to JavaScript files use this identifier to provide values of the given properties. + +For instance, to define an SVG icon in a `block.js` file, you should attach it to the blocks global variable like so: + +```js +blocks[ 'core/heading' ].icon = // SVG element of the icon. +``` + +### Title + +* Type: string +* Required +* Localized: Yes +* Property: `title` + +```json +{ "title": "Heading" } +``` + +This is the display title for your block, which can be translated with our translation functions. The block inserter will show this name. + +### Category + +* Type: string +* Required +* Localized: No +* Property: `category` + +```json +{ "category": "common" } +``` + +Blocks are grouped into categories to help users browse and discover them. + +The core provided categories are: + +* common +* formatting +* layout +* widgets +* embed + +Plugins and Themes can also register [custom block categories](https://wordpress.org/gutenberg/handbook/designers-developers/developers/filters/block-filters/#managing-block-categories). + +An implementation should expect and tolerate unknown categories, providing some reasonable fallback behavior (e.g. a "common" category). + +### Icon + +* Type: object +* Optional +* Localized: No +* Property: `icon` + +```json +{ + "slug": "star", // Dashicon slug, serve as a fallback if non-js contexts. + "src": "./my-file.js", // Path to a JavaScript file containing the block's icon property + "foreground": "#000000", + "background": "#FFFFFF", +} +``` + +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. + +Besides the dashicon or the source of the SVG element, the icon object can contain background and foreground colors, this colors will appear with the icon when they are applicable e.g.: in the inserter. + +**Note:** Custom SVG icons are automatically wrapped in the [wp.components.SVG](https://wordpress.org/gutenberg/handbook/designers-developers/developers/components/svg/) component to add accessibility attributes (aria-hidden, role, and focusable). + + +### Description + +* Type: string +* Optional +* Localized: Yes +* Property: `description` + +```json + { "description": "Introduce new sections and organize content to help visitors" } +``` + +This is a short description for your block, which can be translated with our translation functions. This will be shown in the block inspector. + +### Keywords + +* Type: string[] +* Optional +* Localized: Yes +* Property: `keywords` + +```json +{ "keywords": [ "keyword1", "keyword2" ] } +``` + +Sometimes a block could have aliases that help users discover it while searching. For example, an image block could also want to be discovered by photo. You can do so by providing an array of terms (which can be translated). It is only allowed to add as much as three terms per block. + +### Attributes + +* Type: object +* Optional +* Localized: No +* Property: `attributes` + +```json +{ + "attributes": { + "cover": { + "type": "string", + "source": "attribute", + "selector": "img", + "attribute": "src" + }, + "author": { + "type": "string", + "source": "html", + "selector": ".book-author" + } + } +} +``` + +Attributes provide the structured data needs of a block. They can exist in different forms when they are serialized, but they are declared together under a common interface. + +See the [the attributes documentation](https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-attributes/) for more details. + +### Edit + +* Type: string (`WPDefinedPropertyFile`) +* Optional +* Localized: No +* Property: `edit` + +```json +{ "edit": "my-block-edit.js" } +``` + +This property is a pointer to a JavaScript file containing the edit function of the block type. 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 the [Edit and Save](https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-edit-save/) documentation for more details. + +**Important Note:** + +The `WPDefinedPropertyFile` type described here is a subtype of string, where the value must represent an absolute or relative path to a file by which a dynamic value or values of a property can be interpreted. + +_TBD: Describe the resolution behavior by file extension, and consider further extension-specific subtypes (e.g. WPDefinedJSPropertyFile)._ + +### Save + +* Type: string (`WPDefinedPropertyFile`) +* Optional +* Localized: No +* Property: `save` + +```json +{ "save": "my-block-save.js" } +``` + +This property is a pointer to a JavaScript file containing the save function of the block type. 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 the [Edit and Save](https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-edit-save/) documentation for more details. + +If omitted, the implementation should fall back to one as if it were defined as a function returning `null`, where the expected behavior is to serialize without any inner HTML (a "void block"). + +### Render Callback + +* Type: string (`WPDefinedPropertyFile`) +* Optional +* Localized: No +* Property: `renderCallback` + +```json +{ "renderCallback": "my-block-render-callback.php" } +``` + +This is a pointer to a php file returning a render callback php function. The render callback is function called when the block is rendered on the frontend. It's used to generate the frontend markup dynamically. + +See the [dynamic blocks documentation](https://wordpress.org/gutenberg/handbook/designers-developers/developers/tutorials/block-tutorial/creating-dynamic-blocks/) for more details. + +### Styles Variations + +* Type: array +* Optional +* Localized: No +* Property: `styleVariations` + +```json +{ + "styleVariations": + [ + { "name": "default", "label": "Default", "isDefault": true }, + { "name": "other", "label": "Other" } + ] +} +``` + +Block styles can be used to provide alternative styles to block. It works by adding a class name to the block's wrapper. Using CSS, a theme developer can target the class name for the style variation if it is selected. + +Plugins and Themes can also register [custom block style](https://wordpress.org/gutenberg/handbook/designers-developers/developers/filters/block-filters/#block-style-variations) for existing blocks. + +### Transforms + +* Type: string +* Optional +* Localized: No +* Property: `transforms` + +```json +{ "transforms": "my-block-transforms.js" } +``` + +This property is a pointer to a JavaScript file containing the save function of the block transforms. 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 the [Transforms](https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/#transforms-optional) documentation for more details. + +### Deprecated versions + +* Type: object[] +* Optional +* Localized: No +* Property: `deprecated` + +```json +{ "deprecated": [ { attributes, save, supports } ] } +``` + +This property contains the definition of the deprecated versions of the block type. It is used to ensure that old blocks with old markup are not considered invalid. + +See the [Deprecated Blocks](https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-deprecation/) documentation for more details. + +### Supports + +* Type: object +* Optional +* Localized: No +* Property: `supports` + +Optional block extended support features. + +See the [block supports](https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/#supports-optional) documentation page for more details. + +### Stylesheets + +* Type: object +* Optional +* Localized: No +* Property: `stylesheets` + +```json +{ + "stylesheets": { + "main": "my-block-style.css", + "editor": "my-block-editor-style.css", + "theme": "my-block-theme-style.css" + } +} +``` + +This property is a pointer to CSS files containing the CSS used for the block in different contexts. + +## Internationalization + +Localized properties are automatically wrapped in `__` function calls on the backend and the frontend of WordPress. These translations are added as an inline script to the `wp-block-library` script handle. + +WordPress string discovery automatically includes these strings to the plugin's or core's domain name. + +## PHP Runtime + +WordPress automatically discovers all the block.json files in the plugin/core `blocks` folder and registers the corresponding block types. These block types are made available through the [block registry](https://developer.wordpress.org/reference/classes/wp_block_type_registry/) PHP class and the blocks scripts and styles are added as dependencies to the `wp-block-library` script and style handles. + +## Backward Compatibility + +The existing registration mechanism (both server side and frontend) will continue to work, it will serve as low-level implementation detail for the `block.json` based registration. + +Core Blocks will be migrated iteratively and third-party blocks will see warnings appearing in the console to encourage them to refactor the block registration API used. From 5392e900750873c8afd6c82335f8b94994a78e2f Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Fri, 8 Feb 2019 08:47:41 +0100 Subject: [PATCH 02/33] Update docs/rfc/block-registration.md Co-Authored-By: youknowriad --- docs/rfc/block-registration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index aba539d1f31c8e..28342177c15cf3 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -51,7 +51,7 @@ To register a new block type, start by creating a `block.json` file. This file: * Gives a name to the block type. * Defines some important metadata about the registered block type (title, category, icon, description, keywords). -* Defines the attributes of your block type. +* Defines the attributes of the block type. * Links to the editor implementation of your block type, the save function and any other context-aware property. **Example:** From a3724a53921582eb662cd8a77264d6c14087f67a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Thu, 21 Feb 2019 17:45:40 +0100 Subject: [PATCH 03/33] Fix typo in WordPress name --- docs/rfc/block-registration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index 28342177c15cf3..a34d7f2f796ad8 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -10,7 +10,7 @@ In more practical terms, an implementation should fulfill requirements that... * Building REST APIs to fetch the available block types * Building REST APIs to fetch block objects from posts * This API should be backward compatible with what we have at the moment. -* It should be possible to statically analyze a block type in order to support advanced use-cases required by one of the [9 projects](https://make.wordpress.org/core/2018/12/08/9-priorities-for-2019/) for 2019 in Wordpress: "Building a WordPress.org directory for discovering blocks, and a way to seamlessly install them." +* It should be possible to statically analyze a block type in order to support advanced use-cases required by one of the [9 projects](https://make.wordpress.org/core/2018/12/08/9-priorities-for-2019/) for 2019 in WordPress: "Building a WordPress.org directory for discovering blocks, and a way to seamlessly install them." * It should not require a build tool compilation step (e.g. Babel, Webpack) to author code which would be referenced in a block type definition. * There should allow the potential to dynamically load ("lazy-load") block types, or parts of block type definitions. From 25a2e6c9b8bfa7c4f1a6f627322688b56cf46c49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Thu, 21 Feb 2019 17:56:25 +0100 Subject: [PATCH 04/33] Clarify some points in requirements --- docs/rfc/block-registration.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index a34d7f2f796ad8..8eab77ce0ca837 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -10,9 +10,11 @@ In more practical terms, an implementation should fulfill requirements that... * Building REST APIs to fetch the available block types * Building REST APIs to fetch block objects from posts * This API should be backward compatible with what we have at the moment. -* It should be possible to statically analyze a block type in order to support advanced use-cases required by one of the [9 projects](https://make.wordpress.org/core/2018/12/08/9-priorities-for-2019/) for 2019 in WordPress: "Building a WordPress.org directory for discovering blocks, and a way to seamlessly install them." +* It should be possible to statically analyze a block type in order to support advanced use-cases required by one of the [9 projects](https://make.wordpress.org/core/2018/12/08/9-priorities-for-2019/) for 2019 in WordPress: "Building a WordPress.org directory for discovering blocks, and a way to seamlessly install them.". The block directory should not need to parse JavaScript or PHP files to retrieve their definitions similar to how it happens for plugins as of today. + +It can statically analyze the files of any plugin to retrieve blocks and their properties. * It should not require a build tool compilation step (e.g. Babel, Webpack) to author code which would be referenced in a block type definition. -* There should allow the potential to dynamically load ("lazy-load") block types, or parts of block type definitions. +* There should allow the potential to dynamically load ("lazy-load") block types, or parts of block type definitions. It practical terms, it means that the editor should be able to be loaded without enqueuing all the assets (scripts and styles) of all block types. What it needs is the basic metadata (`title`, `description`, `category`, `icon`, etc...) to start with. It should be fine to defer loading all other code (`edit`, `save`, `transforms`, and other JavaScript implementations) until it is explicitly used (inserted into the post content). ## References From dcf374aae48e605b84f733acc743e9bc12ceabd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Thu, 21 Feb 2019 18:04:21 +0100 Subject: [PATCH 05/33] Update the note about REST API --- docs/rfc/block-registration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index 8eab77ce0ca837..aac85943cf313c 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -7,8 +7,8 @@ Behind any block type registration is some abstract concept of a unit of content In more practical terms, an implementation should fulfill requirements that... * A block type registration should be declarative and context-agnostic. Any runtime (PHP, JS, or other) should be able to interpret the basics of a block type (see "Block API" in the sections below) and should be able to fetch or retrieve the definitions of the context-specific implementation details. The following things should be made possible: - * Building REST APIs to fetch the available block types - * Building REST APIs to fetch block objects from posts + * Fetching the available block types through REST APIs. + * Fetching block objects from posts through REST APIs. * This API should be backward compatible with what we have at the moment. * It should be possible to statically analyze a block type in order to support advanced use-cases required by one of the [9 projects](https://make.wordpress.org/core/2018/12/08/9-priorities-for-2019/) for 2019 in WordPress: "Building a WordPress.org directory for discovering blocks, and a way to seamlessly install them.". The block directory should not need to parse JavaScript or PHP files to retrieve their definitions similar to how it happens for plugins as of today. From 00eab255d6fb88aaf856018e88ab1abbf4ed6c16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Mon, 25 Feb 2019 11:28:08 +0100 Subject: [PATCH 06/33] Removed comments from json based examples --- docs/rfc/block-registration.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index aac85943cf313c..b3655143680360 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -67,7 +67,13 @@ To register a new block type, start by creating a `block.json` file. This file: "icon": "star", "description": "Shows warning, error or success notices ...", "keywords": [ "alert", "message" ], - "attributes": { /* Block attributes definition */ }, + "attributes": { + "message": { + "type": "string", + "source": "html", + "selector": ".meessage" + } + }, "edit": "blocks/notice-edit.js", "save": "blocks/notice-save.js", } @@ -151,14 +157,14 @@ An implementation should expect and tolerate unknown categories, providing some ```json { - "slug": "star", // Dashicon slug, serve as a fallback if non-js contexts. - "src": "./my-file.js", // Path to a JavaScript file containing the block's icon property + "slug": "star", + "src": "./my-file.js", "foreground": "#000000", "background": "#FFFFFF", } ``` -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. +An icon property should be specified to make it easier to identify a block. These can be any of WordPress' Dashicons (slug serving also as a fallback if non-js contexts), and a path to a JavaScript file containing the block's icon property custom SVG element. Besides the dashicon or the source of the SVG element, the icon object can contain background and foreground colors, this colors will appear with the icon when they are applicable e.g.: in the inserter. From 56d859e6538f7a24288f021bfb6a553b88d0d8ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Tue, 5 Mar 2019 12:30:47 +0100 Subject: [PATCH 07/33] Fix icon examples --- docs/rfc/block-registration.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index b3655143680360..d5eebb63759dc5 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -64,7 +64,9 @@ To register a new block type, start by creating a `block.json` file. This file: "name": "my-plugin/notice", "title": "Notice", "category": "common", - "icon": "star", + "icon": { + "slug": "star", + } "description": "Shows warning, error or success notices ...", "keywords": [ "alert", "message" ], "attributes": { @@ -156,12 +158,12 @@ An implementation should expect and tolerate unknown categories, providing some * Property: `icon` ```json -{ +{ "icon": { "slug": "star", "src": "./my-file.js", "foreground": "#000000", "background": "#FFFFFF", -} +} } ``` An icon property should be specified to make it easier to identify a block. These can be any of WordPress' Dashicons (slug serving also as a fallback if non-js contexts), and a path to a JavaScript file containing the block's icon property custom SVG element. From 94d882b87a071030d189692d30befc050bf146fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Tue, 5 Mar 2019 12:31:52 +0100 Subject: [PATCH 08/33] Add missing comma in JSON example --- docs/rfc/block-registration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index d5eebb63759dc5..95e5eb5c0e7077 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -66,7 +66,7 @@ To register a new block type, start by creating a `block.json` file. This file: "category": "common", "icon": { "slug": "star", - } + }, "description": "Shows warning, error or success notices ...", "keywords": [ "alert", "message" ], "attributes": { From 05c8fc304f17827cd16977bbcf2a97f604c0d37c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Tue, 5 Mar 2019 14:27:45 +0100 Subject: [PATCH 09/33] A few smaller tweaks --- docs/rfc/block-registration.md | 39 +++++++++++++++++----------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index 95e5eb5c0e7077..30c12639e682cb 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -64,9 +64,7 @@ To register a new block type, start by creating a `block.json` file. This file: "name": "my-plugin/notice", "title": "Notice", "category": "common", - "icon": { - "slug": "star", - }, + "icon": "star", "description": "Shows warning, error or success notices ...", "keywords": [ "alert", "message" ], "attributes": { @@ -87,7 +85,7 @@ This section describes all the properties that can be added to the `block.json` ### Name -* Type: string +* Type: `string` * Required * Localized: No * Property: `name` @@ -114,7 +112,7 @@ blocks[ 'core/heading' ].icon = // SVG element of the icon. ### Title -* Type: string +* Type: `string` * Required * Localized: Yes * Property: `title` @@ -127,7 +125,7 @@ This is the display title for your block, which can be translated with our trans ### Category -* Type: string +* Type: `string` * Required * Localized: No * Property: `category` @@ -152,11 +150,14 @@ An implementation should expect and tolerate unknown categories, providing some ### Icon -* Type: object +* Type: `string`|`object` * Optional * Localized: No * Property: `icon` +```json +{ "icon": "smile" } +``` ```json { "icon": { "slug": "star", @@ -175,7 +176,7 @@ Besides the dashicon or the source of the SVG element, the icon object can conta ### Description -* Type: string +* Type: `string` * Optional * Localized: Yes * Property: `description` @@ -188,7 +189,7 @@ This is a short description for your block, which can be translated with our tra ### Keywords -* Type: string[] +* Type: `string[]` * Optional * Localized: Yes * Property: `keywords` @@ -201,7 +202,7 @@ Sometimes a block could have aliases that help users discover it while searching ### Attributes -* Type: object +* Type: `object` * Optional * Localized: No * Property: `attributes` @@ -230,7 +231,7 @@ See the [the attributes documentation](https://wordpress.org/gutenberg/handbook/ ### Edit -* Type: string (`WPDefinedPropertyFile`) +* Type: `string` (`WPDefinedPropertyFile`) * Optional * Localized: No * Property: `edit` @@ -251,7 +252,7 @@ _TBD: Describe the resolution behavior by file extension, and consider further e ### Save -* Type: string (`WPDefinedPropertyFile`) +* Type: `string` (`WPDefinedPropertyFile`) * Optional * Localized: No * Property: `save` @@ -268,7 +269,7 @@ If omitted, the implementation should fall back to one as if it were defined as ### Render Callback -* Type: string (`WPDefinedPropertyFile`) +* Type: `string` (`WPDefinedPropertyFile`) * Optional * Localized: No * Property: `renderCallback` @@ -283,7 +284,7 @@ See the [dynamic blocks documentation](https://wordpress.org/gutenberg/handbook/ ### Styles Variations -* Type: array +* Type: `array` * Optional * Localized: No * Property: `styleVariations` @@ -304,7 +305,7 @@ Plugins and Themes can also register [custom block style](https://wordpress.org/ ### Transforms -* Type: string +* Type: `string` * Optional * Localized: No * Property: `transforms` @@ -319,13 +320,13 @@ See the [Transforms](https://wordpress.org/gutenberg/handbook/designers-develope ### Deprecated versions -* Type: object[] +* Type: `object[]` * Optional * Localized: No * Property: `deprecated` ```json -{ "deprecated": [ { attributes, save, supports } ] } +{ "deprecated": [ { attributes: {}, save: "my-deprecated-save.js", supports: {} } ] } ``` This property contains the definition of the deprecated versions of the block type. It is used to ensure that old blocks with old markup are not considered invalid. @@ -334,7 +335,7 @@ See the [Deprecated Blocks](https://wordpress.org/gutenberg/handbook/designers-d ### Supports -* Type: object +* Type: `object` * Optional * Localized: No * Property: `supports` @@ -345,7 +346,7 @@ See the [block supports](https://wordpress.org/gutenberg/handbook/designers-deve ### Stylesheets -* Type: object +* Type: `object` * Optional * Localized: No * Property: `stylesheets` From fb143e4776d4adffc233ed37ea536af2aae4d298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Tue, 5 Mar 2019 14:29:19 +0100 Subject: [PATCH 10/33] Fix to deprecated versions example --- docs/rfc/block-registration.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index 30c12639e682cb..3f0053830a16a5 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -326,7 +326,11 @@ See the [Transforms](https://wordpress.org/gutenberg/handbook/designers-develope * Property: `deprecated` ```json -{ "deprecated": [ { attributes: {}, save: "my-deprecated-save.js", supports: {} } ] } +{ "deprecated": [ { + "attributes": {}, + "save": "my-deprecated-save.js", + "supports": {} +} ] } ``` This property contains the definition of the deprecated versions of the block type. It is used to ensure that old blocks with old markup are not considered invalid. From 7a239237c3f470a18a0f4fd231b88dd0f93b340a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Fri, 15 Mar 2019 12:26:07 +0100 Subject: [PATCH 11/33] Update block-registration.md --- docs/rfc/block-registration.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index 3f0053830a16a5..64c4b7c74c50c7 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -75,7 +75,7 @@ To register a new block type, start by creating a `block.json` file. This file: } }, "edit": "blocks/notice-edit.js", - "save": "blocks/notice-save.js", + "save": "blocks/notice-save.js" } ``` @@ -163,7 +163,7 @@ An implementation should expect and tolerate unknown categories, providing some "slug": "star", "src": "./my-file.js", "foreground": "#000000", - "background": "#FFFFFF", + "background": "#FFFFFF" } } ``` @@ -209,7 +209,7 @@ Sometimes a block could have aliases that help users discover it while searching ```json { - "attributes": { + "attributes": { "cover": { "type": "string", "source": "attribute", @@ -291,11 +291,10 @@ See the [dynamic blocks documentation](https://wordpress.org/gutenberg/handbook/ ```json { - "styleVariations": - [ - { "name": "default", "label": "Default", "isDefault": true }, - { "name": "other", "label": "Other" } - ] + "styleVariations": [ + { "name": "default", "label": "Default", "isDefault": true }, + { "name": "other", "label": "Other" } + ] } ``` From eb580a58746f63a845badcd2837d0d374622b923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Mon, 8 Apr 2019 11:26:43 +0200 Subject: [PATCH 12/33] Update block-registration.md --- docs/rfc/block-registration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index 64c4b7c74c50c7..eb290504d971ba 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -1,3 +1,5 @@ +# Block Type Registration RFC + This RFC is intended to serve both as a specification and as documentation for the implementation of runtime-agnostic block type registration. ## Requirements @@ -41,8 +43,6 @@ Another exploration in [#5652](https://github.com/WordPress/gutenberg/pull/5652) --- -# Block Type Registration RFC - ## Introduction Blocks are the fundamental elements of the editor. They are the primary way in which plugins and themes can register their own functionality and extend the capabilities of the editor. From e6c12082f0369b6ba51feb567cfe59616b8ecdf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Mon, 8 Apr 2019 11:28:16 +0200 Subject: [PATCH 13/33] Update block-registration.md --- docs/rfc/block-registration.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index eb290504d971ba..b9739cc013d9ee 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -23,6 +23,7 @@ It can statically analyze the files of any plugin to retrieve blocks and their p * Issue: [Block API: Server-side awareness of block types](https://github.com/WordPress/gutenberg/issues/2751) * Follow-up issue: [Expose available blocks via an API](https://github.com/WordPress/gutenberg/issues/4116) * Current documentation: [https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/](https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/) +* Make WordPress.org post: [The Block Directory, and a new type of plugin](https://make.wordpress.org/meta/2019/03/08/the-block-directory-and-a-new-type-of-plugin/) ## Previous attempts From f2aa6d7a1cc1d64db6550f9e0120d4a986acda0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Mon, 8 Apr 2019 13:24:46 +0200 Subject: [PATCH 14/33] Update block-registration.md --- docs/rfc/block-registration.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index b9739cc013d9ee..a34994b0cb628f 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -369,10 +369,40 @@ This property is a pointer to CSS files containing the CSS used for the block in ## Internationalization -Localized properties are automatically wrapped in `__` function calls on the backend and the frontend of WordPress. These translations are added as an inline script to the `wp-block-library` script handle. +Localized properties are automatically wrapped in `_x` function calls on the backend and the frontend of WordPress. These translations are added as an inline script to the `wp-block-library` script handle in WordPress core or to the plugin's script handle which defines block when loading metadata defintion. WordPress string discovery automatically includes these strings to the plugin's or core's domain name. +**Example:** + +```json +{ + "title": "My block", + "description": "My block is fantastic", + "keywords": [ "fanstastic" ] +} +``` + +in JavScript with help of Babel plugin becomes: + +```js +const metadata = { + title: _x( 'My block', 'block title', 'my-plugin' ), + description: _x( 'My block is fantastic', 'block description', 'my-plugin' ), + keywords: [ _x( 'fanstastic', 'block keywords', 'my-plugin' ) ], +} +``` + +in PHP it gets transformed on the fly to code close to: + +```php +$metadata = array( + 'title' => _x( 'My block', 'block title', 'my-plugin' ), + 'description': _x( 'My block is fantastic', 'block description', 'my-plugin' ), + 'keywords': array( _x( 'fanstastic', 'block keywords', 'my-plugin' ) ), +); +``` + ## PHP Runtime WordPress automatically discovers all the block.json files in the plugin/core `blocks` folder and registers the corresponding block types. These block types are made available through the [block registry](https://developer.wordpress.org/reference/classes/wp_block_type_registry/) PHP class and the blocks scripts and styles are added as dependencies to the `wp-block-library` script and style handles. From 152326f488c3a0f9fbe0fabf51e09a182a34e391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Mon, 8 Apr 2019 13:26:55 +0200 Subject: [PATCH 15/33] Update block-registration.md --- docs/rfc/block-registration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index a34994b0cb628f..61a4ceecd9bee9 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -369,7 +369,7 @@ This property is a pointer to CSS files containing the CSS used for the block in ## Internationalization -Localized properties are automatically wrapped in `_x` function calls on the backend and the frontend of WordPress. These translations are added as an inline script to the `wp-block-library` script handle in WordPress core or to the plugin's script handle which defines block when loading metadata defintion. +Localized properties are automatically wrapped in `_x` function calls on the backend and the frontend of WordPress. These translations are added as an inline script to the `wp-block-library` script handle in WordPress core or to the plugin's script handle when it defines metadata defintion. WordPress string discovery automatically includes these strings to the plugin's or core's domain name. From f87879af9838319d39f29c3c03d5fa4a0b09bbcf Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Mon, 8 Apr 2019 17:45:15 +0200 Subject: [PATCH 16/33] Apply suggestions from code review Co-Authored-By: gziolo --- docs/rfc/block-registration.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index 61a4ceecd9bee9..2840946866bf94 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -371,7 +371,7 @@ This property is a pointer to CSS files containing the CSS used for the block in Localized properties are automatically wrapped in `_x` function calls on the backend and the frontend of WordPress. These translations are added as an inline script to the `wp-block-library` script handle in WordPress core or to the plugin's script handle when it defines metadata defintion. -WordPress string discovery automatically includes these strings to the plugin's or core's domain name. +WordPress string discovery automatically translates these strings using the `textdomain` value specified in the plugin header. **Example:** @@ -383,7 +383,7 @@ WordPress string discovery automatically includes these strings to the plugin's } ``` -in JavScript with help of Babel plugin becomes: +In JavaScript, with the help of a Babel plugin, this becomes: ```js const metadata = { @@ -393,7 +393,7 @@ const metadata = { } ``` -in PHP it gets transformed on the fly to code close to: +In PHP, it is transformed at runtime to code roughly equivalent to: ```php $metadata = array( From 8a183900335bf7a4c70b2cfdfe443c54721f91ad Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Mon, 8 Apr 2019 17:45:53 +0200 Subject: [PATCH 17/33] Update docs/rfc/block-registration.md Co-Authored-By: gziolo --- docs/rfc/block-registration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index 2840946866bf94..60c45dc19b17a9 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -369,7 +369,7 @@ This property is a pointer to CSS files containing the CSS used for the block in ## Internationalization -Localized properties are automatically wrapped in `_x` function calls on the backend and the frontend of WordPress. These translations are added as an inline script to the `wp-block-library` script handle in WordPress core or to the plugin's script handle when it defines metadata defintion. +Localized properties are automatically wrapped in `_x` function calls on the back end and the front end of WordPress. These translations are added as an inline script to the `wp-block-library` script handle in WordPress core or to the plugin's script handle when it defines metadata definition. WordPress string discovery automatically translates these strings using the `textdomain` value specified in the plugin header. From a8faacb966af409b143a320c360fa4b1987f41e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Mon, 8 Apr 2019 17:52:48 +0200 Subject: [PATCH 18/33] Update block-registration.md --- docs/rfc/block-registration.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index 60c45dc19b17a9..d75a3d2a1cf712 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -403,6 +403,8 @@ $metadata = array( ); ``` +Implementation should follow the existing [get_plugin_data](https://codex.wordpress.org/Function_Reference/get_plugin_data) function which parses the plugin contents to retrieve the plugin’s metadata, and it applies translations dynamically. + ## PHP Runtime WordPress automatically discovers all the block.json files in the plugin/core `blocks` folder and registers the corresponding block types. These block types are made available through the [block registry](https://developer.wordpress.org/reference/classes/wp_block_type_registry/) PHP class and the blocks scripts and styles are added as dependencies to the `wp-block-library` script and style handles. From e1f90baee32a50a5edf24771c13ce64290eb02ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Sun, 14 Apr 2019 16:55:11 +0200 Subject: [PATCH 19/33] Add missing `parent` attribute --- docs/rfc/block-registration.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index d75a3d2a1cf712..8afef16075e10e 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -65,6 +65,7 @@ To register a new block type, start by creating a `block.json` file. This file: "name": "my-plugin/notice", "title": "Notice", "category": "common", + "parent": [ "core/group" ], "icon": "star", "description": "Shows warning, error or success notices ...", "keywords": [ "alert", "message" ], @@ -149,6 +150,19 @@ Plugins and Themes can also register [custom block categories](https://wordpress An implementation should expect and tolerate unknown categories, providing some reasonable fallback behavior (e.g. a "common" category). +### Parent + +* Type: `string[]` +* Optional +* Localized: No +* Property: `parent` + +```json +{ "parent": [ "my-block/product" ] } +``` + +Setting `parent` lets a block require that it is only available when nested within the specified blocks. For example, you might want to allow an 'Add to Cart' block to only be available within a 'Product' block. + ### Icon * Type: `string`|`object` @@ -199,7 +213,7 @@ This is a short description for your block, which can be translated with our tra { "keywords": [ "keyword1", "keyword2" ] } ``` -Sometimes a block could have aliases that help users discover it while searching. For example, an image block could also want to be discovered by photo. You can do so by providing an array of terms (which can be translated). It is only allowed to add as much as three terms per block. +Sometimes a block could have aliases that help users discover it while searching. For example, an image block could also want to be discovered by photo. You can do so by providing an array of unlimited terms (which are translated). ### Attributes From 503a194a9f8da9080c86f783626fd68a4c4a3597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Sun, 14 Apr 2019 17:11:28 +0200 Subject: [PATCH 20/33] Update block-registration.md --- docs/rfc/block-registration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index 8afef16075e10e..69f5b54e9b6bc7 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -301,7 +301,7 @@ See the [dynamic blocks documentation](https://wordpress.org/gutenberg/handbook/ * Type: `array` * Optional -* Localized: No +* Localized: Yes (`label`) * Property: `styleVariations` ```json From 2fbfb2e5e5d784182ef94413213ca1cf240d1c49 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Fri, 19 Apr 2019 16:18:34 +0200 Subject: [PATCH 21/33] Add backward compatibility section --- docs/rfc/block-registration.md | 43 ++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index 69f5b54e9b6bc7..07b769982a7654 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -319,7 +319,7 @@ Plugins and Themes can also register [custom block style](https://wordpress.org/ ### Transforms -* Type: `string` +* Type: `string` (`WPDefinedPropertyFile`) * Optional * Localized: No * Property: `transforms` @@ -334,34 +334,19 @@ See the [Transforms](https://wordpress.org/gutenberg/handbook/designers-develope ### Deprecated versions -* Type: `object[]` +* Type: `string` (`WPDefinedPropertyFile`) * Optional * Localized: No * Property: `deprecated` ```json -{ "deprecated": [ { - "attributes": {}, - "save": "my-deprecated-save.js", - "supports": {} -} ] } +{ "deprecated": "my-block-deprecated.js" } ``` This property contains the definition of the deprecated versions of the block type. It is used to ensure that old blocks with old markup are not considered invalid. See the [Deprecated Blocks](https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-deprecation/) documentation for more details. -### Supports - -* Type: `object` -* Optional -* Localized: No -* Property: `supports` - -Optional block extended support features. - -See the [block supports](https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/#supports-optional) documentation page for more details. - ### Stylesheets * Type: `object` @@ -381,6 +366,28 @@ See the [block supports](https://wordpress.org/gutenberg/handbook/designers-deve This property is a pointer to CSS files containing the CSS used for the block in different contexts. +## Backward compatibility + +There are 3 properties that are going to supported for backward compatibility reasons and are going to be replaced with alternative APIs: + - `supports` - see the [block supports](https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/#supports-optional) documentation page for more details. + - `merge` - not documented as of today. + - `getEditWrapperProps` - not documented as well. + +**Example**: +```js +wp.blocks.registerBlockType( 'my-block/name', { + edit: function() { + // Edit definition goes here. + }, + save: function() { + // Save definition goes here. + }, + supports: { + html: false + } +} ); +``` + ## Internationalization Localized properties are automatically wrapped in `_x` function calls on the back end and the front end of WordPress. These translations are added as an inline script to the `wp-block-library` script handle in WordPress core or to the plugin's script handle when it defines metadata definition. From 9d7478a0cc474fa057cab8b61f26dcafbbf6eb8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Fri, 19 Apr 2019 16:26:11 +0200 Subject: [PATCH 22/33] Apply suggestions from code review --- docs/rfc/block-registration.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index 07b769982a7654..ce95f68344637f 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -368,10 +368,10 @@ This property is a pointer to CSS files containing the CSS used for the block in ## Backward compatibility -There are 3 properties that are going to supported for backward compatibility reasons and are going to be replaced with alternative APIs: +Three properties are going to be supported for backward compatibility reasons on the client-side, and they are going to be replaced with alternative APIs in the future: - `supports` - see the [block supports](https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/#supports-optional) documentation page for more details. - - `merge` - not documented as of today. - - `getEditWrapperProps` - not documented as well. + - `merge` - undocumented as of today. Its role is to handle merging multiple blocks into one. + - `getEditWrapperProps` - undocumented as well. Its role is to inject additional props to the block edit's component wrapper. **Example**: ```js From 11a816a1a29980932dca07cd2e8ac26351941e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Tue, 23 Apr 2019 14:51:28 +0200 Subject: [PATCH 23/33] Align the name of style variations with the existing usage --- docs/rfc/block-registration.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index ce95f68344637f..e15bb65ce641e3 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -77,7 +77,11 @@ To register a new block type, start by creating a `block.json` file. This file: } }, "edit": "blocks/notice-edit.js", - "save": "blocks/notice-save.js" + "save": "blocks/notice-save.js", + "styles": [ + { "name": "default", "label": "Default", "isDefault": true }, + { "name": "other", "label": "Other" } + ] } ``` @@ -297,16 +301,16 @@ This is a pointer to a php file returning a render callback php function. The r See the [dynamic blocks documentation](https://wordpress.org/gutenberg/handbook/designers-developers/developers/tutorials/block-tutorial/creating-dynamic-blocks/) for more details. -### Styles Variations +### Style Variations * Type: `array` * Optional * Localized: Yes (`label`) -* Property: `styleVariations` +* Property: `styles` ```json { - "styleVariations": [ + "styles": [ { "name": "default", "label": "Default", "isDefault": true }, { "name": "other", "label": "Other" } ] From 54557fc97dd27eb72ddfdf9e7332845fd16d4e4a Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Tue, 21 May 2019 14:50:58 +0200 Subject: [PATCH 24/33] Update RFC with all details about handling scripts and styles --- docs/rfc/block-registration.md | 312 +++++++++++++++++++++------------ 1 file changed, 197 insertions(+), 115 deletions(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index e15bb65ce641e3..e3fd77c5c01161 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -22,13 +22,13 @@ It can statically analyze the files of any plugin to retrieve blocks and their p * Issue: [Block API: Server-side awareness of block types](https://github.com/WordPress/gutenberg/issues/2751) * Follow-up issue: [Expose available blocks via an API](https://github.com/WordPress/gutenberg/issues/4116) -* Current documentation: [https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/](https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/) +* Current documentation: [/docs/designers-developers/developers/block-api/block-registration.md](/docs/designers-developers/developers/block-api/block-registration.md) * Make WordPress.org post: [The Block Directory, and a new type of plugin](https://make.wordpress.org/meta/2019/03/08/the-block-directory-and-a-new-type-of-plugin/) ## Previous attempts -Initial support for server-defined block attributes was merged as part of [#2529](https://github.com/WordPress/gutenberg/pull/2529). PHP block type registrations are merged with those defined in the JavaScript runtime. While this enabled blocks to be defined within PHP, the majority of block types continue to be defined within JavaScript alone. The support was reserved for the exclusive use of [dynamic block types](https://wordpress.org/gutenberg/handbook/designers-developers/developers/tutorials/block-tutorial/creating-dynamic-blocks/), in large part because [edit and save behaviors](https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-edit-save/) must still be implemented in JavaScript, and because a solution hadn't been considered for how to create individual block bundles during the build process, nor how to load such bundles efficiently if it were to come to be implemented. +Initial support for server-defined block attributes was merged as part of [#2529](https://github.com/WordPress/gutenberg/pull/2529). PHP block type registrations are merged with those defined in the JavaScript runtime. While this enabled blocks to be defined within PHP, the majority of block types continue to be defined within JavaScript alone. The support was reserved for the exclusive use of [dynamic block types](/docs/designers-developers/developers/tutorials/block-tutorial/creating-dynamic-blocks.md), in large part because [edit and save behaviors](/docs/designers-developers/developers/block-api/block-edit-save.md) must still be implemented in JavaScript, and because a solution hadn't been considered for how to create individual block bundles during the build process, nor how to load such bundles efficiently if it were to come to be implemented. A demonstration for how block registration could be made filterable in PHP was explored in [#5802](https://github.com/WordPress/gutenberg/pull/5802). The purpose here was to explore how plugins could have better control over the registration. @@ -55,7 +55,7 @@ To register a new block type, start by creating a `block.json` file. This file: * Gives a name to the block type. * Defines some important metadata about the registered block type (title, category, icon, description, keywords). * Defines the attributes of the block type. -* Links to the editor implementation of your block type, the save function and any other context-aware property. +* Registers all the scripts and styles for your block type. **Example:** @@ -69,6 +69,7 @@ To register a new block type, start by creating a `block.json` file. This file: "icon": "star", "description": "Shows warning, error or success notices ...", "keywords": [ "alert", "message" ], + "textDomain": "my-plugin", "attributes": { "message": { "type": "string", @@ -76,12 +77,24 @@ To register a new block type, start by creating a `block.json` file. This file: "selector": ".meessage" } }, - "edit": "blocks/notice-edit.js", - "save": "blocks/notice-save.js", "styles": [ { "name": "default", "label": "Default", "isDefault": true }, { "name": "other", "label": "Other" } - ] + ], + "editorScript": "file:build/editor.assets.json", + "script": { + "handle": "my-plugin-notice", + "file": "index.js", + "dependencies": [ "wp-element", "wp-components" ], + "version": "3.0.0" + }, + "editorStyle": { + "handle": "my-plugin-notice-editor", + "file": "editor.css", + "dependencies": [ "wp-edit-blocks" ] + }, + "style": "my-plugin-notice", + "renderCallback": "file:my-render-callback.php" } ``` @@ -106,16 +119,6 @@ The name for a block is a unique string that identifies a block. Names have to b **Note:** This name is used on the comment delimiters as ``. Block types in the `core` namespace do not include a namespace when serialized. -**Important Note:** - -Other block properties that point to JavaScript files use this identifier to provide values of the given properties. - -For instance, to define an SVG icon in a `block.js` file, you should attach it to the blocks global variable like so: - -```js -blocks[ 'core/heading' ].icon = // SVG element of the icon. -``` - ### Title * Type: `string` @@ -150,7 +153,7 @@ The core provided categories are: * widgets * embed -Plugins and Themes can also register [custom block categories](https://wordpress.org/gutenberg/handbook/designers-developers/developers/filters/block-filters/#managing-block-categories). +Plugins and Themes can also register [custom block categories](/docs/designers-developers/developers/filters/block-filters.md#managing-block-categories). An implementation should expect and tolerate unknown categories, providing some reasonable fallback behavior (e.g. a "common" category). @@ -169,7 +172,7 @@ Setting `parent` lets a block require that it is only available when nested with ### Icon -* Type: `string`|`object` +* Type: `string`` * Optional * Localized: No * Property: `icon` @@ -177,21 +180,10 @@ Setting `parent` lets a block require that it is only available when nested with ```json { "icon": "smile" } ``` -```json -{ "icon": { - "slug": "star", - "src": "./my-file.js", - "foreground": "#000000", - "background": "#FFFFFF" -} } -``` - -An icon property should be specified to make it easier to identify a block. These can be any of WordPress' Dashicons (slug serving also as a fallback if non-js contexts), and a path to a JavaScript file containing the block's icon property custom SVG element. -Besides the dashicon or the source of the SVG element, the icon object can contain background and foreground colors, this colors will appear with the icon when they are applicable e.g.: in the inserter. - -**Note:** Custom SVG icons are automatically wrapped in the [wp.components.SVG](https://wordpress.org/gutenberg/handbook/designers-developers/developers/components/svg/) component to add accessibility attributes (aria-hidden, role, and focusable). +An icon property should be specified to make it easier to identify a block. These can be any of WordPress' Dashicons (slug serving also as a fallback in non-js contexts). +**Note:** It's also possible to override this property on the client-side with the source of the SVG element. In addition, this property can be defined with JavaScript as an object containing background and foreground colors. This colors will appear with the icon when they are applicable e.g.: in the inserter. Custom SVG icons are automatically wrapped in the [wp.components.SVG](/packages/components/src/primitives/svg/README.md) component to add accessibility attributes (aria-hidden, role, and focusable). ### Description @@ -219,6 +211,19 @@ This is a short description for your block, which can be translated with our tra Sometimes a block could have aliases that help users discover it while searching. For example, an image block could also want to be discovered by photo. You can do so by providing an array of unlimited terms (which are translated). +### Text Domain + +* Type: `string` +* Optional +* Localized: No +* Property: `textDomain` + +```json +{ "textDomain": "my-plugin" } +``` + +The [gettext](https://www.gnu.org/software/gettext/) text domain of the plugin/block. More information can be found in the [Text Domain](https://developer.wordpress.org/plugins/internationalization/how-to-internationalize-your-plugin/#text-domains) section of the [How to Internationalize your Plugin](https://developer.wordpress.org/plugins/internationalization/how-to-internationalize-your-plugin/) page. + ### Attributes * Type: `object` @@ -246,134 +251,116 @@ Sometimes a block could have aliases that help users discover it while searching Attributes provide the structured data needs of a block. They can exist in different forms when they are serialized, but they are declared together under a common interface. -See the [the attributes documentation](https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-attributes/) for more details. +See the [the attributes documentation](/docs/designers-developers/developers/block-api/block-attributes.md) for more details. -### Edit +### Style Variations -* Type: `string` (`WPDefinedPropertyFile`) -* Optional -* Localized: No -* Property: `edit` +* Type: `array` +* Optional +* Localized: Yes (`label`) +* Property: `styles` ```json -{ "edit": "my-block-edit.js" } +{ + "styles": [ + { "name": "default", "label": "Default", "isDefault": true }, + { "name": "other", "label": "Other" } + ] +} ``` -This property is a pointer to a JavaScript file containing the edit function of the block type. 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 the [Edit and Save](https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-edit-save/) documentation for more details. - -**Important Note:** - -The `WPDefinedPropertyFile` type described here is a subtype of string, where the value must represent an absolute or relative path to a file by which a dynamic value or values of a property can be interpreted. +Block styles can be used to provide alternative styles to block. It works by adding a class name to the block's wrapper. Using CSS, a theme developer can target the class name for the style variation if it is selected. -_TBD: Describe the resolution behavior by file extension, and consider further extension-specific subtypes (e.g. WPDefinedJSPropertyFile)._ +Plugins and Themes can also register [custom block style](/docs/designers-developers/developers/filters/block-filters.md#block-style-variations) for existing blocks. -### Save +### Editor Script -* Type: `string` (`WPDefinedPropertyFile`) +* Type: `string|object` ([WPDefinedAsset](#WPDefinedAsset)) * Optional * Localized: No -* Property: `save` +* Property: `editorScript` ```json -{ "save": "my-block-save.js" } +{ "editorScript": "file:build/editor.assets.json" } ``` -This property is a pointer to a JavaScript file containing the save function of the block type. 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 the [Edit and Save](https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-edit-save/) documentation for more details. +Block type editor script definition. It will only be enqueued in the context of the editor. -If omitted, the implementation should fall back to one as if it were defined as a function returning `null`, where the expected behavior is to serialize without any inner HTML (a "void block"). +### Script -### Render Callback - -* Type: `string` (`WPDefinedPropertyFile`) +* Type: `string|object` ([WPDefinedAsset](#WPDefinedAsset)) * Optional * Localized: No -* Property: `renderCallback` +* Property: `script` ```json -{ "renderCallback": "my-block-render-callback.php" } -``` - -This is a pointer to a php file returning a render callback php function. The render callback is function called when the block is rendered on the frontend. It's used to generate the frontend markup dynamically. - -See the [dynamic blocks documentation](https://wordpress.org/gutenberg/handbook/designers-developers/developers/tutorials/block-tutorial/creating-dynamic-blocks/) for more details. - -### Style Variations - -* Type: `array` -* Optional -* Localized: Yes (`label`) -* Property: `styles` - -```json -{ - "styles": [ - { "name": "default", "label": "Default", "isDefault": true }, - { "name": "other", "label": "Other" } - ] +{ + "script": { + "handle": "my-plugin-notice", + "file": "index.js", + "dependencies": [ "wp-element", "wp-components" ], + "version": "3.0.0" + } } ``` -Block styles can be used to provide alternative styles to block. It works by adding a class name to the block's wrapper. Using CSS, a theme developer can target the class name for the style variation if it is selected. +Block type frontend script definition. It will be enqueued both in the editor and when viewing the content on the front of the site. -Plugins and Themes can also register [custom block style](https://wordpress.org/gutenberg/handbook/designers-developers/developers/filters/block-filters/#block-style-variations) for existing blocks. +### Editor Style -### Transforms - -* Type: `string` (`WPDefinedPropertyFile`) +* Type: `string|object` ([WPDefinedAsset](#WPDefinedAsset)) * Optional * Localized: No -* Property: `transforms` +* Property: `editorStyle` ```json -{ "transforms": "my-block-transforms.js" } +{ + "editorStyle": { + "handle": "my-plugin-notice-editor", + "file": "editor.css", + "dependencies": [ "wp-edit-blocks" ] + } +} ``` -This property is a pointer to a JavaScript file containing the save function of the block transforms. 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`. +Block type editor style definition. It will only be enqueued in the context of the editor. -See the [Transforms](https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/#transforms-optional) documentation for more details. +### Style -### Deprecated versions - -* Type: `string` (`WPDefinedPropertyFile`) +* Type: `string|object` ([WPDefinedAsset](#WPDefinedAsset)) * Optional * Localized: No -* Property: `deprecated` +* Property: `style` ```json -{ "deprecated": "my-block-deprecated.js" } +{ "style": "my-plugin-notice" } ``` -This property contains the definition of the deprecated versions of the block type. It is used to ensure that old blocks with old markup are not considered invalid. - -See the [Deprecated Blocks](https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-deprecation/) documentation for more details. +Block type frontend style definition. It will be enqueued both in the editor and when viewing the content on the front of the site. -### Stylesheets +### Render Callback -* Type: `object` +* Type: `string` ([WPDefinedPropertyFile](#WPDefinedPropertyFile)) * Optional * Localized: No -* Property: `stylesheets` +* Property: `renderCallback` ```json -{ - "stylesheets": { - "main": "my-block-style.css", - "editor": "my-block-editor-style.css", - "theme": "my-block-theme-style.css" - } -} +{ "renderCallback": "file:my-render-callback.php" } ``` -This property is a pointer to CSS files containing the CSS used for the block in different contexts. +This is a pointer to a php file returning a render callback php function. The render callback is function called when the block is rendered on the frontend. It's used to generate the frontend markup dynamically. + +See the [dynamic blocks documentation](/docs/designers-developers/developers/tutorials/block-tutorial/creating-dynamic-blocks.md) for more details. ## Backward compatibility -Three properties are going to be supported for backward compatibility reasons on the client-side, and they are going to be replaced with alternative APIs in the future: - - `supports` - see the [block supports](https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/#supports-optional) documentation page for more details. +The following properties are going to be supported for backward compatibility reasons on the client-side only. Some of them might be replaced with alternative APIs in the future: + - `edit` - see the [Edit and Save](/docs/designers-developers/developers/block-api/block-edit-save.md) documentation for more details. + - `save` - see the [Edit and Save](/docs/designers-developers/developers/block-api/block-edit-save.md) documentation for more details. + - `transforms` - see the [Transforms](/docs/designers-developers/developers/block-api/block-registration.md#transforms-optional) documentation for more details. + - `deprecated` - see the [Deprecated Blocks](/docs/designers-developers/developers/block-api/block-deprecation.md) documentation for more details. + - `supports` - see the [block supports](/docs/designers-developers/developers/block-api/block-registration.md#supports-optional) documentation page for more details. - `merge` - undocumented as of today. Its role is to handle merging multiple blocks into one. - `getEditWrapperProps` - undocumented as well. Its role is to inject additional props to the block edit's component wrapper. @@ -392,11 +379,104 @@ wp.blocks.registerBlockType( 'my-block/name', { } ); ``` +## Assets + +### `WPDefinedAsset` + +The `WPDefinedAsset` type mirrors the shape of params necessary to register scripts and styles using [`wp_register_script`](https://developer.wordpress.org/reference/functions/wp_register_script/) and [`wp_register_style`](https://developer.wordpress.org/reference/functions/wp_register_style/), and then assign these as handles associated with your block using the `script`, `style`, `editor_script`, and `editor_style` block type registration settings. There are three ways you can use them with `block.json` metadata. + +#### Handle + +First, in WordPress context, it's possible to register a script or style with a regular PHP function call and then assign the handle (`string`) to the corresponding property in `block.json` file. + +**Example:** + +In `index.php`: +```php +wp_register_script( + 'my-plugin-notice-editor', + plugins_url( 'build/editor.js', __FILE__ ), + array( 'wp-blocks', 'wp-element', 'wp-i18n' ), + '3.0.0' +); +``` + +In `block.json`: +```json +{ "editorScript": "my-plugin-notice-editor" } +``` + +#### Object + +An asset can also be defined as an object which takes the following shape: +- `handle` (`string`) - the name of the script. +- `file` (`string`) - full URL of the script, or path of the script relative to the WordPress root directory. +- `dependencies` (`string[]` - optional) - an array of registered script handles this script depends on. Default value: `array()`. +- `version` (`string`|`bool`|`null` - optional) - string specifying the script version number, if it has one, which is added to the URL as a query string for cache busting purposes. If the version is set to `false`, a version number is automatically added equal to current installed WordPress version. If set to `null`, no version is added. Default value: `false`. + +When a block is registered with PHP, it will also automatically register all scripts and styles that are found in the `block.json` file. + +**Example:** + +In `block.json`: +```json +{ + "editorScript": { + "handle": "my-plugin-notice-editor", + "file": "build/editor.js", + "dependencies": [ "wp-blocks","wp-element", "wp-i18n" ], + "version": "3.0.0" + } +} +``` + +#### File reference + +It's almost identical to the `object` option. The only difference is that it is stored inside its JSON file and referenced in `block.json` with __"file:"__ prefix (this mirrors how [local paths](https://docs.npmjs.com/files/package.json#local-paths) work in npm). This option is the preferred one as we are going to provide a way to auto-generate those asset files with `@wordpress/scripts` package. + +**Example:** + +In `build/editor.asset.json`: +```json +{ + "handle": "my-plugin-notice-editor", + "file": "build/editor.js", + "dependencies": [ "wp-blocks","wp-element", "wp-i18n" ], + "version": "3.0.0" +} +``` + +In `block.json`: +```json +{ "editorScript": "file:build/editor.asset.json" } +``` + +### `WPDefinedPropertyFile` + +The `WPDefinedPropertyFile` type is a subtype of string, where the value must represent an absolute or relative path to a PHP file by which a dynamic value can be interpreted. This file should return a function or a callback of type [callable](https://www.php.net/manual/en/language.types.callable.php). + +**Example:** + +In `render-callback.php`: + +```php + _x( 'My block', 'block title', 'my-plugin' ), - 'description': _x( 'My block is fantastic', 'block description', 'my-plugin' ), - 'keywords': array( _x( 'fanstastic', 'block keywords', 'my-plugin' ) ), + 'title' => _x( 'My block', 'block title', 'my-plugin' ), + 'description' => _x( 'My block is fantastic!', 'block description', 'my-plugin' ), + 'keywords' => array( _x( 'fantastic', 'block keywords', 'my-plugin' ) ), ); ``` From 9a8fd0b409ee86ebda977bf6d293a547a364a361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Fri, 24 May 2019 10:57:52 +0200 Subject: [PATCH 25/33] Apply suggestions from code review Co-Authored-By: Jon Surrell Co-Authored-By: Andrew Duthie --- docs/rfc/block-registration.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index e3fd77c5c01161..59b69516656471 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -81,7 +81,7 @@ To register a new block type, start by creating a `block.json` file. This file: { "name": "default", "label": "Default", "isDefault": true }, { "name": "other", "label": "Other" } ], - "editorScript": "file:build/editor.assets.json", + "editorScript": "file:build/editor.asset.json", "script": { "handle": "my-plugin-notice", "file": "index.js", @@ -172,7 +172,7 @@ Setting `parent` lets a block require that it is only available when nested with ### Icon -* Type: `string`` +* Type: `string` * Optional * Localized: No * Property: `icon` @@ -281,7 +281,7 @@ Plugins and Themes can also register [custom block style](/docs/designers-develo * Property: `editorScript` ```json -{ "editorScript": "file:build/editor.assets.json" } +{ "editorScript": "file:build/editor.asset.json" } ``` Block type editor script definition. It will only be enqueued in the context of the editor. @@ -412,7 +412,7 @@ An asset can also be defined as an object which takes the following shape: - `handle` (`string`) - the name of the script. - `file` (`string`) - full URL of the script, or path of the script relative to the WordPress root directory. - `dependencies` (`string[]` - optional) - an array of registered script handles this script depends on. Default value: `array()`. -- `version` (`string`|`bool`|`null` - optional) - string specifying the script version number, if it has one, which is added to the URL as a query string for cache busting purposes. If the version is set to `false`, a version number is automatically added equal to current installed WordPress version. If set to `null`, no version is added. Default value: `false`. +- `version` (`string`|`false`|`null` - optional) - string specifying the script version number, if it has one, which is added to the URL as a query string for cache busting purposes. If the version is set to `false`, a version number is automatically added equal to current installed WordPress version. If set to `null`, no version is added. Default value: `false`. When a block is registered with PHP, it will also automatically register all scripts and styles that are found in the `block.json` file. From 0bd77939ef86d8d2f22fe97723c55ae6d2d92ffa Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Fri, 24 May 2019 13:57:27 +0200 Subject: [PATCH 26/33] Replace spaces with tabs for identation --- docs/rfc/block-registration.md | 28 +++++++++---------- packages/e2e-tests/plugins/hooks-api/index.js | 24 ++++++++++++++++ 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index 59b69516656471..058b9766dc2319 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -367,15 +367,15 @@ The following properties are going to be supported for backward compatibility re **Example**: ```js wp.blocks.registerBlockType( 'my-block/name', { - edit: function() { - // Edit definition goes here. - }, - save: function() { - // Save definition goes here. - }, - supports: { - html: false - } + edit: function() { + // Edit definition goes here. + }, + save: function() { + // Save definition goes here. + }, + supports: { + html: false + } } ); ``` @@ -422,11 +422,11 @@ In `block.json`: ```json { "editorScript": { - "handle": "my-plugin-notice-editor", - "file": "build/editor.js", - "dependencies": [ "wp-blocks","wp-element", "wp-i18n" ], - "version": "3.0.0" - } + "handle": "my-plugin-notice-editor", + "file": "build/editor.js", + "dependencies": [ "wp-blocks","wp-element", "wp-i18n" ], + "version": "3.0.0" + } } ``` diff --git a/packages/e2e-tests/plugins/hooks-api/index.js b/packages/e2e-tests/plugins/hooks-api/index.js index 3cfe4ca1590322..3e504a6b63ed68 100644 --- a/packages/e2e-tests/plugins/hooks-api/index.js +++ b/packages/e2e-tests/plugins/hooks-api/index.js @@ -58,4 +58,28 @@ addResetBlockButton, 100 ); + + var withInspectorControls = wp.compose.createHigherOrderComponent( function( BlockEdit ) { + return function( props ) { + return el( + Fragment, + {}, + el( + BlockEdit, + props + ), + el( + InspectorControls, + {}, + el( + wp.components.PanelBody, + {}, + 'My custom control' + ) + ) + ); + }; + }, 'withInspectorControls' ); + + addFilter( 'editor.BlockEdit', 'my-plugin/with-inspector-controls', withInspectorControls ); } )(); From 8092c1945dca86275e8c5029b377846eb098d1a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Tue, 28 May 2019 11:46:54 +0200 Subject: [PATCH 27/33] Update docs/rfc/block-registration.md Co-Authored-By: Andrew Duthie --- docs/rfc/block-registration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index 058b9766dc2319..b6e6206ba63c75 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -28,7 +28,7 @@ It can statically analyze the files of any plugin to retrieve blocks and their p ## Previous attempts -Initial support for server-defined block attributes was merged as part of [#2529](https://github.com/WordPress/gutenberg/pull/2529). PHP block type registrations are merged with those defined in the JavaScript runtime. While this enabled blocks to be defined within PHP, the majority of block types continue to be defined within JavaScript alone. The support was reserved for the exclusive use of [dynamic block types](/docs/designers-developers/developers/tutorials/block-tutorial/creating-dynamic-blocks.md), in large part because [edit and save behaviors](/docs/designers-developers/developers/block-api/block-edit-save.md) must still be implemented in JavaScript, and because a solution hadn't been considered for how to create individual block bundles during the build process, nor how to load such bundles efficiently if it were to come to be implemented. +Initial support for server-defined block attributes was merged as part of [#2529](https://github.com/WordPress/gutenberg/pull/2529). PHP block type registrations are merged with those defined in the JavaScript runtime. While this enabled blocks to be defined within PHP, the majority of block types continue to be defined within JavaScript alone. The support was reserved for the exclusive use of [dynamic block types](/docs/designers-developers/developers/tutorials/block-tutorial/creating-dynamic-blocks.md), in large part because [`edit` and `save` behaviors](/docs/designers-developers/developers/block-api/block-edit-save.md) must still be implemented in JavaScript, and because a solution hadn't been considered for how to create individual block bundles during the build process, nor how to load such bundles efficiently if it were to come to be implemented. A demonstration for how block registration could be made filterable in PHP was explored in [#5802](https://github.com/WordPress/gutenberg/pull/5802). The purpose here was to explore how plugins could have better control over the registration. From dcf6b63d0c0a0015cf6b35f576fcd6c6a55069c0 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Tue, 28 May 2019 11:51:33 +0200 Subject: [PATCH 28/33] Remove debugging code from test plugin --- packages/e2e-tests/plugins/hooks-api/index.js | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/packages/e2e-tests/plugins/hooks-api/index.js b/packages/e2e-tests/plugins/hooks-api/index.js index 3e504a6b63ed68..3cfe4ca1590322 100644 --- a/packages/e2e-tests/plugins/hooks-api/index.js +++ b/packages/e2e-tests/plugins/hooks-api/index.js @@ -58,28 +58,4 @@ addResetBlockButton, 100 ); - - var withInspectorControls = wp.compose.createHigherOrderComponent( function( BlockEdit ) { - return function( props ) { - return el( - Fragment, - {}, - el( - BlockEdit, - props - ), - el( - InspectorControls, - {}, - el( - wp.components.PanelBody, - {}, - 'My custom control' - ) - ) - ); - }; - }, 'withInspectorControls' ); - - addFilter( 'editor.BlockEdit', 'my-plugin/with-inspector-controls', withInspectorControls ); } )(); From 4c7ec7f57edde6410c7f23ccec1808769edaacb0 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Tue, 28 May 2019 13:26:56 +0200 Subject: [PATCH 29/33] Try simplify the way WPDefinedAsset is defined --- docs/rfc/block-registration.md | 68 ++++++++++++++++------------------ 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index b6e6206ba63c75..3049a61a185ed2 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -77,11 +77,11 @@ To register a new block type, start by creating a `block.json` file. This file: "selector": ".meessage" } }, - "styles": [ + "styleVariations": [ { "name": "default", "label": "Default", "isDefault": true }, { "name": "other", "label": "Other" } ], - "editorScript": "file:build/editor.asset.json", + "editorScript": "build/editor.asset.json", "script": { "handle": "my-plugin-notice", "file": "index.js", @@ -94,7 +94,7 @@ To register a new block type, start by creating a `block.json` file. This file: "dependencies": [ "wp-edit-blocks" ] }, "style": "my-plugin-notice", - "renderCallback": "file:my-render-callback.php" + "renderCallback": "my-render-callback.php" } ``` @@ -255,14 +255,15 @@ See the [the attributes documentation](/docs/designers-developers/developers/blo ### Style Variations -* Type: `array` -* Optional -* Localized: Yes (`label`) -* Property: `styles` +* Type: `array` +* Optional +* Localized: Yes (`label`) +* Property: `styleVariations` +* Alias: `styles` ```json { - "styles": [ + "styleVariations": [ { "name": "default", "label": "Default", "isDefault": true }, { "name": "other", "label": "Other" } ] @@ -281,7 +282,7 @@ Plugins and Themes can also register [custom block style](/docs/designers-develo * Property: `editorScript` ```json -{ "editorScript": "file:build/editor.asset.json" } +{ "editorScript": "build/editor.js" } ``` Block type editor script definition. It will only be enqueued in the context of the editor. @@ -333,7 +334,7 @@ Block type editor style definition. It will only be enqueued in the context of t * Property: `style` ```json -{ "style": "my-plugin-notice" } +{ "style": "build/style.css" } ``` Block type frontend style definition. It will be enqueued both in the editor and when viewing the content on the front of the site. @@ -346,7 +347,7 @@ Block type frontend style definition. It will be enqueued both in the editor and * Property: `renderCallback` ```json -{ "renderCallback": "file:my-render-callback.php" } +{ "renderCallback": "my-render-callback.php" } ``` This is a pointer to a php file returning a render callback php function. The render callback is function called when the block is rendered on the frontend. It's used to generate the frontend markup dynamically. @@ -383,38 +384,26 @@ wp.blocks.registerBlockType( 'my-block/name', { ### `WPDefinedAsset` -The `WPDefinedAsset` type mirrors the shape of params necessary to register scripts and styles using [`wp_register_script`](https://developer.wordpress.org/reference/functions/wp_register_script/) and [`wp_register_style`](https://developer.wordpress.org/reference/functions/wp_register_style/), and then assign these as handles associated with your block using the `script`, `style`, `editor_script`, and `editor_style` block type registration settings. There are three ways you can use them with `block.json` metadata. - -#### Handle - -First, in WordPress context, it's possible to register a script or style with a regular PHP function call and then assign the handle (`string`) to the corresponding property in `block.json` file. +The `WPDefinedAsset` type is either a subtype of string, where the value must represent an absolute or relative path to a JavaScript or CSS file, or an object. **Example:** -In `index.php`: -```php -wp_register_script( - 'my-plugin-notice-editor', - plugins_url( 'build/editor.js', __FILE__ ), - array( 'wp-blocks', 'wp-element', 'wp-i18n' ), - '3.0.0' -); -``` - In `block.json`: ```json -{ "editorScript": "my-plugin-notice-editor" } +{ "editorScript": "build/editor.js" } ``` +In the context of WordPress, the `WPDefinedAsset` type has to mirror also the shape of params necessary to register scripts and styles using [`wp_register_script`](https://developer.wordpress.org/reference/functions/wp_register_script/) and [`wp_register_style`](https://developer.wordpress.org/reference/functions/wp_register_style/), and then assign these as handles associated with your block using the `script`, `style`, `editor_script`, and `editor_style` block type registration settings. There are two ways you can use `WPDefinedAsset` with `block.json` metadata. + #### Object -An asset can also be defined as an object which takes the following shape: +An asset can be defined as an object which takes the following shape: - `handle` (`string`) - the name of the script. - `file` (`string`) - full URL of the script, or path of the script relative to the WordPress root directory. - `dependencies` (`string[]` - optional) - an array of registered script handles this script depends on. Default value: `array()`. - `version` (`string`|`false`|`null` - optional) - string specifying the script version number, if it has one, which is added to the URL as a query string for cache busting purposes. If the version is set to `false`, a version number is automatically added equal to current installed WordPress version. If set to `null`, no version is added. Default value: `false`. -When a block is registered with PHP, it will also automatically register all scripts and styles that are found in the `block.json` file. +When a block is registered with PHP, it will automatically register all scripts and styles that are found in the `block.json` file. **Example:** @@ -432,25 +421,30 @@ In `block.json`: #### File reference -It's almost identical to the `object` option. The only difference is that it is stored inside its JSON file and referenced in `block.json` with __"file:"__ prefix (this mirrors how [local paths](https://docs.npmjs.com/files/package.json#local-paths) work in npm). This option is the preferred one as we are going to provide a way to auto-generate those asset files with `@wordpress/scripts` package. +It's very similar to the `object` option. The only difference is that the definition is stored inside separate JSON file which ends with `.asset.json` and is located next to the JS/CSS file listed in `block.json`. WordPress will automatically detect this file through pattern matching. This option is the preferred one as we are going to provide a way to auto-generate those asset files with `@wordpress/scripts` package. **Example:** +``` +build/ +├─ editor.js +└─ editor.asset.json +``` + +In `block.json`: +```json +{ "editorScript": "build/editor.js" } +``` + In `build/editor.asset.json`: ```json { "handle": "my-plugin-notice-editor", - "file": "build/editor.js", "dependencies": [ "wp-blocks","wp-element", "wp-i18n" ], "version": "3.0.0" } ``` -In `block.json`: -```json -{ "editorScript": "file:build/editor.asset.json" } -``` - ### `WPDefinedPropertyFile` The `WPDefinedPropertyFile` type is a subtype of string, where the value must represent an absolute or relative path to a PHP file by which a dynamic value can be interpreted. This file should return a function or a callback of type [callable](https://www.php.net/manual/en/language.types.callable.php). @@ -469,7 +463,7 @@ return 'render_block_my_block'; In `block.json`: ```json -{ "renderCallback": "file:render-callback.php" } +{ "renderCallback": "render-callback.php" } ``` ## Internationalization From ea11bf7337e9cee056eeb78b5c4980ac835376e0 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Thu, 6 Jun 2019 15:51:07 +0200 Subject: [PATCH 30/33] Docs: Remove `render_callback` property from the initial version of RFC --- docs/rfc/block-registration.md | 41 +++------------------------------- 1 file changed, 3 insertions(+), 38 deletions(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index 3049a61a185ed2..44756268eeb599 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -93,8 +93,7 @@ To register a new block type, start by creating a `block.json` file. This file: "file": "editor.css", "dependencies": [ "wp-edit-blocks" ] }, - "style": "my-plugin-notice", - "renderCallback": "my-render-callback.php" + "style": "build/style.css" } ``` @@ -339,21 +338,6 @@ Block type editor style definition. It will only be enqueued in the context of t Block type frontend style definition. It will be enqueued both in the editor and when viewing the content on the front of the site. -### Render Callback - -* Type: `string` ([WPDefinedPropertyFile](#WPDefinedPropertyFile)) -* Optional -* Localized: No -* Property: `renderCallback` - -```json -{ "renderCallback": "my-render-callback.php" } -``` - -This is a pointer to a php file returning a render callback php function. The render callback is function called when the block is rendered on the frontend. It's used to generate the frontend markup dynamically. - -See the [dynamic blocks documentation](/docs/designers-developers/developers/tutorials/block-tutorial/creating-dynamic-blocks.md) for more details. - ## Backward compatibility The following properties are going to be supported for backward compatibility reasons on the client-side only. Some of them might be replaced with alternative APIs in the future: @@ -380,6 +364,8 @@ wp.blocks.registerBlockType( 'my-block/name', { } ); ``` +In the case of [dynamic blocks](/docs/designers-developers/developers/tutorials/block-tutorial/creating-dynamic-blocks.md) supported by WordPress, it should be still possible to register `render_callback` property using [`register_block_type`](https://developer.wordpress.org/reference/functions/register_block_type/) function on the server. + ## Assets ### `WPDefinedAsset` @@ -445,27 +431,6 @@ In `build/editor.asset.json`: } ``` -### `WPDefinedPropertyFile` - -The `WPDefinedPropertyFile` type is a subtype of string, where the value must represent an absolute or relative path to a PHP file by which a dynamic value can be interpreted. This file should return a function or a callback of type [callable](https://www.php.net/manual/en/language.types.callable.php). - -**Example:** - -In `render-callback.php`: - -```php - Date: Mon, 10 Jun 2019 17:28:55 +0200 Subject: [PATCH 31/33] Further simplify the definition of assets and clarify how it works with WordPress --- docs/rfc/block-registration.md | 79 +++++++++------------------------- 1 file changed, 20 insertions(+), 59 deletions(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index 44756268eeb599..02ddaee98e0c3a 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -81,18 +81,9 @@ To register a new block type, start by creating a `block.json` file. This file: { "name": "default", "label": "Default", "isDefault": true }, { "name": "other", "label": "Other" } ], - "editorScript": "build/editor.asset.json", - "script": { - "handle": "my-plugin-notice", - "file": "index.js", - "dependencies": [ "wp-element", "wp-components" ], - "version": "3.0.0" - }, - "editorStyle": { - "handle": "my-plugin-notice-editor", - "file": "editor.css", - "dependencies": [ "wp-edit-blocks" ] - }, + "editorScript": "build/editor.js", + "script": "build/main.js", + "editorStyle": "build/editor.css", "style": "build/style.css" } ``` @@ -257,8 +248,8 @@ See the [the attributes documentation](/docs/designers-developers/developers/blo * Type: `array` * Optional * Localized: Yes (`label`) -* Property: `styleVariations` -* Alias: `styles` +* Property: `styles` +* Alias: `styleVariations` ```json { @@ -275,7 +266,7 @@ Plugins and Themes can also register [custom block style](/docs/designers-develo ### Editor Script -* Type: `string|object` ([WPDefinedAsset](#WPDefinedAsset)) +* Type: `string` ([WPDefinedAsset](#WPDefinedAsset)) * Optional * Localized: No * Property: `editorScript` @@ -288,46 +279,33 @@ Block type editor script definition. It will only be enqueued in the context of ### Script -* Type: `string|object` ([WPDefinedAsset](#WPDefinedAsset)) +* Type: `string` ([WPDefinedAsset](#WPDefinedAsset)) * Optional * Localized: No * Property: `script` ```json -{ - "script": { - "handle": "my-plugin-notice", - "file": "index.js", - "dependencies": [ "wp-element", "wp-components" ], - "version": "3.0.0" - } -} +{ "script": "build/main.js" } ``` Block type frontend script definition. It will be enqueued both in the editor and when viewing the content on the front of the site. ### Editor Style -* Type: `string|object` ([WPDefinedAsset](#WPDefinedAsset)) +* Type: `string` ([WPDefinedAsset](#WPDefinedAsset)) * Optional * Localized: No * Property: `editorStyle` ```json -{ - "editorStyle": { - "handle": "my-plugin-notice-editor", - "file": "editor.css", - "dependencies": [ "wp-edit-blocks" ] - } -} +{ "editorStyle": "build/editor.css" } ``` Block type editor style definition. It will only be enqueued in the context of the editor. ### Style -* Type: `string|object` ([WPDefinedAsset](#WPDefinedAsset)) +* Type: `string` ([WPDefinedAsset](#WPDefinedAsset)) * Optional * Localized: No * Property: `style` @@ -370,7 +348,7 @@ In the case of [dynamic blocks](/docs/designers-developers/developers/tutorials/ ### `WPDefinedAsset` -The `WPDefinedAsset` type is either a subtype of string, where the value must represent an absolute or relative path to a JavaScript or CSS file, or an object. +The `WPDefinedAsset` type is a subtype of string, where the value must represent an absolute or relative path to a JavaScript or CSS file. **Example:** @@ -379,35 +357,18 @@ In `block.json`: { "editorScript": "build/editor.js" } ``` -In the context of WordPress, the `WPDefinedAsset` type has to mirror also the shape of params necessary to register scripts and styles using [`wp_register_script`](https://developer.wordpress.org/reference/functions/wp_register_script/) and [`wp_register_style`](https://developer.wordpress.org/reference/functions/wp_register_style/), and then assign these as handles associated with your block using the `script`, `style`, `editor_script`, and `editor_style` block type registration settings. There are two ways you can use `WPDefinedAsset` with `block.json` metadata. - -#### Object +#### WordPress context -An asset can be defined as an object which takes the following shape: -- `handle` (`string`) - the name of the script. -- `file` (`string`) - full URL of the script, or path of the script relative to the WordPress root directory. -- `dependencies` (`string[]` - optional) - an array of registered script handles this script depends on. Default value: `array()`. -- `version` (`string`|`false`|`null` - optional) - string specifying the script version number, if it has one, which is added to the URL as a query string for cache busting purposes. If the version is set to `false`, a version number is automatically added equal to current installed WordPress version. If set to `null`, no version is added. Default value: `false`. +In the context of WordPress, when a block is registered with PHP, it will automatically register all scripts and styles that are found in the `block.json` file. -When a block is registered with PHP, it will automatically register all scripts and styles that are found in the `block.json` file. - -**Example:** - -In `block.json`: -```json -{ - "editorScript": { - "handle": "my-plugin-notice-editor", - "file": "build/editor.js", - "dependencies": [ "wp-blocks","wp-element", "wp-i18n" ], - "version": "3.0.0" - } -} -``` +That's why, the `WPDefinedAsset` type has to offer a way to mirror also the shape of params necessary to register scripts and styles using [`wp_register_script`](https://developer.wordpress.org/reference/functions/wp_register_script/) and [`wp_register_style`](https://developer.wordpress.org/reference/functions/wp_register_style/), and then assign these as handles associated with your block using the `script`, `style`, `editor_script`, and `editor_style` block type registration settings. -#### File reference +It's possible to provide an object which takes the following shape: +- `handle` (`string`) - the name of the script. If omitted, it will be auto-generated. +- `dependencies` (`string[]`) - an array of registered script handles this script depends on. Default value: `array()`. +- `version` (`string`|`false`|`null`) - string specifying the script version number, if it has one, which is added to the URL as a query string for cache busting purposes. If the version is set to `false`, a version number is automatically added equal to current installed WordPress version. If set to `null`, no version is added. Default value: `false`. -It's very similar to the `object` option. The only difference is that the definition is stored inside separate JSON file which ends with `.asset.json` and is located next to the JS/CSS file listed in `block.json`. WordPress will automatically detect this file through pattern matching. This option is the preferred one as we are going to provide a way to auto-generate those asset files with `@wordpress/scripts` package. +The definition is stored inside separate JSON file which ends with `.asset.json` and is located next to the JS/CSS file listed in `block.json`. WordPress will automatically detect this file through pattern matching. This option is the preferred one as we are going to provide a way to auto-generate those asset files with `@wordpress/scripts` package. **Example:** From edade1370f633c0963b4194ad2f8e682da8c2dac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Thu, 13 Jun 2019 12:28:24 +0200 Subject: [PATCH 32/33] Apply suggestions from code review Co-Authored-By: Jorge Bernal Co-Authored-By: Andrew Duthie --- docs/rfc/block-registration.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index 02ddaee98e0c3a..d1e3d625d77918 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -74,7 +74,7 @@ To register a new block type, start by creating a `block.json` file. This file: "message": { "type": "string", "source": "html", - "selector": ".meessage" + "selector": ".message" } }, "styleVariations": [ @@ -365,10 +365,10 @@ That's why, the `WPDefinedAsset` type has to offer a way to mirror also the shap It's possible to provide an object which takes the following shape: - `handle` (`string`) - the name of the script. If omitted, it will be auto-generated. -- `dependencies` (`string[]`) - an array of registered script handles this script depends on. Default value: `array()`. +- `dependencies` (`string[]`) - an array of registered script handles this script depends on. Default value: `[]`. - `version` (`string`|`false`|`null`) - string specifying the script version number, if it has one, which is added to the URL as a query string for cache busting purposes. If the version is set to `false`, a version number is automatically added equal to current installed WordPress version. If set to `null`, no version is added. Default value: `false`. -The definition is stored inside separate JSON file which ends with `.asset.json` and is located next to the JS/CSS file listed in `block.json`. WordPress will automatically detect this file through pattern matching. This option is the preferred one as we are going to provide a way to auto-generate those asset files with `@wordpress/scripts` package. +The definition is stored inside separate JSON file which ends with `.asset.json` and is located next to the JS/CSS file listed in `block.json`. WordPress will automatically detect this file through pattern matching. This option is the preferred one as it is expected it will become an option to auto-generate those asset files with `@wordpress/scripts` package. **Example:** From f3456fe079cac7e744efb0de6b3220c99781d1ad Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Tue, 18 Jun 2019 10:41:27 +0200 Subject: [PATCH 33/33] Remove the section about PHP runtime --- docs/rfc/block-registration.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/rfc/block-registration.md b/docs/rfc/block-registration.md index d1e3d625d77918..6c5f3ce2dfe0d9 100644 --- a/docs/rfc/block-registration.md +++ b/docs/rfc/block-registration.md @@ -432,10 +432,6 @@ $metadata = array( Implementation should follow the existing [get_plugin_data](https://codex.wordpress.org/Function_Reference/get_plugin_data) function which parses the plugin contents to retrieve the plugin’s metadata, and it applies translations dynamically. -## PHP Runtime - -WordPress automatically discovers all the block.json files in the plugin/core `blocks` folder and registers the corresponding block types. These block types are made available through the [block registry](https://developer.wordpress.org/reference/classes/wp_block_type_registry/) PHP class and the blocks scripts and styles are added as dependencies to the `wp-block-library` script and style handles. - ## Backward Compatibility The existing registration mechanism (both server side and frontend) will continue to work, it will serve as low-level implementation detail for the `block.json` based registration.