From 0759a789a0af25e78a887cebaaf4e8759bc5719a Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Tue, 19 Mar 2019 10:57:28 +0100 Subject: [PATCH 1/2] Blocks API: Add default implementation for save setting --- .../developers/block-api/block-edit-save.md | 2 +- .../block-tutorial/creating-dynamic-blocks.md | 26 +++---------------- packages/block-library/src/archives/index.js | 5 ---- packages/block-library/src/calendar/index.js | 4 --- .../block-library/src/categories/index.js | 4 --- .../src/latest-comments/index.js | 4 --- .../block-library/src/latest-posts/index.js | 4 --- .../block-library/src/legacy-widget/index.js | 5 ---- packages/block-library/src/rss/index.js | 4 --- packages/block-library/src/search/index.js | 4 --- packages/block-library/src/tag-cloud/index.js | 4 --- packages/blocks/src/api/registration.js | 3 ++- packages/blocks/src/api/test/registration.js | 21 ++++++++------- 13 files changed, 18 insertions(+), 72 deletions(-) diff --git a/docs/designers-developers/developers/block-api/block-edit-save.md b/docs/designers-developers/developers/block-api/block-edit-save.md index c5e35eddb10a7..c9f219b85b817 100644 --- a/docs/designers-developers/developers/block-api/block-edit-save.md +++ b/docs/designers-developers/developers/block-api/block-edit-save.md @@ -226,7 +226,7 @@ For most blocks, the return value of `save` should be an [instance of WordPress _Note:_ While it is possible to return a string value from `save`, it _will be escaped_. If the string includes HTML markup, the markup will be shown on the front of the site verbatim, not as the equivalent HTML node content. If you must return raw HTML from `save`, use `wp.element.RawHTML`. As the name implies, this is prone to [cross-site scripting](https://en.wikipedia.org/wiki/Cross-site_scripting) and therefore is discouraged in favor of a WordPress Element hierarchy whenever possible. -For [dynamic blocks](/docs/designers-developers/developers/tutorials/block-tutorial/creating-dynamic-blocks.md), the return value of `save` could either represent a cached copy of the block's content to be shown only in case the plugin implementing the block is ever disabled. Alternatively, return a `null` (empty) value to save no markup in post content for the dynamic block, instead deferring this to always be calculated when the block is shown on the front of the site. +For [dynamic blocks](/docs/designers-developers/developers/tutorials/block-tutorial/creating-dynamic-blocks.md), the return value of `save` could either represent a cached copy of the block's content to be shown only in case the plugin implementing the block is ever disabled. Alternatively, you can use a built-in implementation which returns a `null` (empty) value to save no markup in post content for the dynamic block, instead deferring this to always be calculated when the block is shown on the front of the site. ### attributes diff --git a/docs/designers-developers/developers/tutorials/block-tutorial/creating-dynamic-blocks.md b/docs/designers-developers/developers/tutorials/block-tutorial/creating-dynamic-blocks.md index aa785ff85e31f..ab7543c392c9c 100644 --- a/docs/designers-developers/developers/tutorials/block-tutorial/creating-dynamic-blocks.md +++ b/docs/designers-developers/developers/tutorials/block-tutorial/creating-dynamic-blocks.md @@ -40,11 +40,6 @@ registerBlockType( 'my-plugin/latest-post', { post.title.rendered ); } ), - - save: function() { - // Rendering in PHP - return null; - }, } ); ``` {% ESNext %} @@ -79,16 +74,11 @@ registerBlockType( 'my-plugin/latest-post', { { post.title.rendered } ; } ), - - save() { - // Rendering in PHP - return null; - }, } ); ``` {% end %} -Because it is a dynamic block it also needs a server component. The rendering can be added using the `render_callback` property when using the `register_block_type` function. +Because it is a dynamic block it doesn't need to override the default `save` implementation on the client. Instead, it needs a server component. The rendering can be added using the `render_callback` property when using the `register_block_type` function. ```php ); }, - - save() { - // Rendering in PHP - return null; - }, } ); ``` {% end %} diff --git a/packages/block-library/src/archives/index.js b/packages/block-library/src/archives/index.js index b523701fcfae4..a9a11bca417b9 100644 --- a/packages/block-library/src/archives/index.js +++ b/packages/block-library/src/archives/index.js @@ -32,9 +32,4 @@ export const settings = { }, edit, - - save() { - // Handled by PHP. - return null; - }, }; diff --git a/packages/block-library/src/calendar/index.js b/packages/block-library/src/calendar/index.js index da8f02dbe4038..56c3c59868603 100644 --- a/packages/block-library/src/calendar/index.js +++ b/packages/block-library/src/calendar/index.js @@ -26,8 +26,4 @@ export const settings = { }, edit, - - save() { - return null; - }, }; diff --git a/packages/block-library/src/categories/index.js b/packages/block-library/src/categories/index.js index 4c65b50840059..8eccf1abf963e 100644 --- a/packages/block-library/src/categories/index.js +++ b/packages/block-library/src/categories/index.js @@ -42,8 +42,4 @@ export const settings = { }, edit, - - save() { - return null; - }, }; diff --git a/packages/block-library/src/latest-comments/index.js b/packages/block-library/src/latest-comments/index.js index 3f0700543f3b1..4f2e500502305 100644 --- a/packages/block-library/src/latest-comments/index.js +++ b/packages/block-library/src/latest-comments/index.js @@ -28,8 +28,4 @@ export const settings = { }, edit, - - save() { - return null; - }, }; diff --git a/packages/block-library/src/latest-posts/index.js b/packages/block-library/src/latest-posts/index.js index e1dd91ea70af8..40ad1d03d0e48 100644 --- a/packages/block-library/src/latest-posts/index.js +++ b/packages/block-library/src/latest-posts/index.js @@ -34,8 +34,4 @@ export const settings = { }, edit, - - save() { - return null; - }, }; diff --git a/packages/block-library/src/legacy-widget/index.js b/packages/block-library/src/legacy-widget/index.js index 43142ec5ca130..b7a4ae1f02151 100644 --- a/packages/block-library/src/legacy-widget/index.js +++ b/packages/block-library/src/legacy-widget/index.js @@ -25,9 +25,4 @@ export const settings = { }, edit, - - save() { - // Handled by PHP. - return null; - }, }; diff --git a/packages/block-library/src/rss/index.js b/packages/block-library/src/rss/index.js index 6a0f916c7d6e5..bd8d523eb6285 100644 --- a/packages/block-library/src/rss/index.js +++ b/packages/block-library/src/rss/index.js @@ -26,8 +26,4 @@ export const settings = { }, edit, - - save() { - return null; - }, }; diff --git a/packages/block-library/src/search/index.js b/packages/block-library/src/search/index.js index 0fcfa75722ff4..4d51919e5d663 100644 --- a/packages/block-library/src/search/index.js +++ b/packages/block-library/src/search/index.js @@ -22,8 +22,4 @@ export const settings = { keywords: [ __( 'find' ) ], edit, - - save() { - return null; - }, }; diff --git a/packages/block-library/src/tag-cloud/index.js b/packages/block-library/src/tag-cloud/index.js index cc785fdb3167a..92121ce0248ac 100644 --- a/packages/block-library/src/tag-cloud/index.js +++ b/packages/block-library/src/tag-cloud/index.js @@ -25,8 +25,4 @@ export const settings = { }, edit, - - save() { - return null; - }, }; diff --git a/packages/blocks/src/api/registration.js b/packages/blocks/src/api/registration.js index d32a49f8b7ff0..727ee171f2b79 100644 --- a/packages/blocks/src/api/registration.js +++ b/packages/blocks/src/api/registration.js @@ -33,7 +33,7 @@ import { isValidIcon, normalizeIconObject } from './utils'; * @property {?string[]} keywords Additional keywords to produce * block as inserter search result. * @property {?Object} attributes Block attributes. - * @property {Function} save Serialize behavior of a block, + * @property {?Function} save Serialize behavior of a block, * returning an element describing * structure of the block's post * content markup. @@ -66,6 +66,7 @@ export function unstable__bootstrapServerSideBlockDefinitions( definitions ) { / export function registerBlockType( name, settings ) { settings = { name, + save: () => null, ...get( serverSideBlockDefinitions, name ), ...settings, }; diff --git a/packages/blocks/src/api/test/registration.js b/packages/blocks/src/api/test/registration.js index f7b20bcda9db0..7b47b97afb840 100644 --- a/packages/blocks/src/api/test/registration.js +++ b/packages/blocks/src/api/test/registration.js @@ -3,12 +3,12 @@ /** * External dependencies */ -import { noop } from 'lodash'; +import { noop, omit } from 'lodash'; /** * WordPress dependencies */ -import { addFilter, removeFilter } from '@wordpress/hooks'; +import { addFilter, removeAllFilters } from '@wordpress/hooks'; /** * Internal dependencies @@ -106,12 +106,6 @@ describe( 'blocks', () => { expect( block ).toBeUndefined(); } ); - it( 'should reject blocks without a save function', () => { - const block = registerBlockType( 'my-plugin/fancy-block-5' ); - expect( console ).toHaveErroredWith( 'The "save" property must be specified and must be a valid function.' ); - expect( block ).toBeUndefined(); - } ); - it( 'should reject blocks with an invalid edit function', () => { const blockType = { save: noop, edit: 'not-a-function', category: 'common', title: 'block title' }, block = registerBlockType( 'my-plugin/fancy-block-6', blockType ); @@ -309,7 +303,7 @@ describe( 'blocks', () => { describe( 'applyFilters', () => { afterEach( () => { - removeFilter( 'blocks.registerBlockType', 'core/blocks/without-title' ); + removeAllFilters( 'blocks.registerBlockType' ); } ); it( 'should reject valid blocks when they become invalid after executing filter', () => { @@ -323,6 +317,15 @@ describe( 'blocks', () => { expect( console ).toHaveErroredWith( 'The block "my-plugin/fancy-block-12" must have a title.' ); expect( block ).toBeUndefined(); } ); + + it( 'should reject valid blocks when they become invalid after executing filter which removes save property', () => { + addFilter( 'blocks.registerBlockType', 'core/blocks/without-save', ( settings ) => { + return omit( settings, 'save' ); + } ); + const block = registerBlockType( 'my-plugin/fancy-block-13', defaultBlockSettings ); + expect( console ).toHaveErroredWith( 'The "save" property must be specified and must be a valid function.' ); + expect( block ).toBeUndefined(); + } ); } ); } ); From cc070f11cd298b23823099df82e4825dc964ec2a Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Tue, 19 Mar 2019 19:48:49 +0100 Subject: [PATCH 2/2] Update docs/designers-developers/developers/block-api/block-edit-save.md Co-Authored-By: gziolo --- .../developers/block-api/block-edit-save.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/designers-developers/developers/block-api/block-edit-save.md b/docs/designers-developers/developers/block-api/block-edit-save.md index c9f219b85b817..fc69abc553e9f 100644 --- a/docs/designers-developers/developers/block-api/block-edit-save.md +++ b/docs/designers-developers/developers/block-api/block-edit-save.md @@ -226,7 +226,9 @@ For most blocks, the return value of `save` should be an [instance of WordPress _Note:_ While it is possible to return a string value from `save`, it _will be escaped_. If the string includes HTML markup, the markup will be shown on the front of the site verbatim, not as the equivalent HTML node content. If you must return raw HTML from `save`, use `wp.element.RawHTML`. As the name implies, this is prone to [cross-site scripting](https://en.wikipedia.org/wiki/Cross-site_scripting) and therefore is discouraged in favor of a WordPress Element hierarchy whenever possible. -For [dynamic blocks](/docs/designers-developers/developers/tutorials/block-tutorial/creating-dynamic-blocks.md), the return value of `save` could either represent a cached copy of the block's content to be shown only in case the plugin implementing the block is ever disabled. Alternatively, you can use a built-in implementation which returns a `null` (empty) value to save no markup in post content for the dynamic block, instead deferring this to always be calculated when the block is shown on the front of the site. +For [dynamic blocks](/docs/designers-developers/developers/tutorials/block-tutorial/creating-dynamic-blocks.md), the return value of `save` could represent a cached copy of the block's content to be shown only in case the plugin implementing the block is ever disabled. + +If left unspecified, the default implementation will save no markup in post content for the dynamic block, instead deferring this to always be calculated when the block is shown on the front of the site. ### attributes