Skip to content

Commit

Permalink
Blocks API: Add default implementation for save setting (#14510)
Browse files Browse the repository at this point in the history
* Blocks API: Add default implementation for save setting

* Update docs/designers-developers/developers/block-api/block-edit-save.md

Co-Authored-By: gziolo <[email protected]>
  • Loading branch information
gziolo authored Mar 20, 2019
1 parent d661666 commit 4d65116
Show file tree
Hide file tree
Showing 13 changed files with 20 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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, 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 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@ registerBlockType( 'my-plugin/latest-post', {
post.title.rendered
);
} ),

save: function() {
// Rendering in PHP
return null;
},
} );
```
{% ESNext %}
Expand Down Expand Up @@ -79,16 +74,11 @@ registerBlockType( 'my-plugin/latest-post', {
{ post.title.rendered }
</a>;
} ),

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
<?php
Expand Down Expand Up @@ -118,8 +108,8 @@ register_block_type( 'my-plugin/latest-post', array(

There are a few things to notice:

* The edit function still shows a representation of the block in the editor's context (this could be very different from the rendered version, it's up to the block's author)
* The save function just returns null because the rendering is performed server-side.
* The `edit` function still shows a representation of the block in the editor's context (this could be very different from the rendered version, it's up to the block's author)
* The built-in `save` function just returns `null` because the rendering is performed server-side.
* The server-side rendering is a function taking the block attributes and the block inner content as arguments, and returning the markup (quite similar to shortcodes)

## Live rendering in Gutenberg editor
Expand Down Expand Up @@ -151,11 +141,6 @@ registerBlockType( 'my-plugin/latest-post', {
})
);
},

save: function() {
// Rendering in PHP
return null;
},
} );
```
{% ESNext %}
Expand All @@ -179,11 +164,6 @@ registerBlockType( 'my-plugin/latest-post', {
/>
);
},

save() {
// Rendering in PHP
return null;
},
} );
```
{% end %}
Expand Down
5 changes: 0 additions & 5 deletions packages/block-library/src/archives/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,4 @@ export const settings = {
},

edit,

save() {
// Handled by PHP.
return null;
},
};
4 changes: 0 additions & 4 deletions packages/block-library/src/calendar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,4 @@ export const settings = {
},

edit,

save() {
return null;
},
};
4 changes: 0 additions & 4 deletions packages/block-library/src/categories/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,4 @@ export const settings = {
},

edit,

save() {
return null;
},
};
4 changes: 0 additions & 4 deletions packages/block-library/src/latest-comments/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,4 @@ export const settings = {
},

edit,

save() {
return null;
},
};
4 changes: 0 additions & 4 deletions packages/block-library/src/latest-posts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,4 @@ export const settings = {
},

edit,

save() {
return null;
},
};
5 changes: 0 additions & 5 deletions packages/block-library/src/legacy-widget/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,4 @@ export const settings = {
},

edit,

save() {
// Handled by PHP.
return null;
},
};
4 changes: 0 additions & 4 deletions packages/block-library/src/rss/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,4 @@ export const settings = {
},

edit,

save() {
return null;
},
};
4 changes: 0 additions & 4 deletions packages/block-library/src/search/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,4 @@ export const settings = {
keywords: [ __( 'find' ) ],

edit,

save() {
return null;
},
};
4 changes: 0 additions & 4 deletions packages/block-library/src/tag-cloud/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,4 @@ export const settings = {
},

edit,

save() {
return null;
},
};
3 changes: 2 additions & 1 deletion packages/blocks/src/api/registration.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -66,6 +66,7 @@ export function unstable__bootstrapServerSideBlockDefinitions( definitions ) { /
export function registerBlockType( name, settings ) {
settings = {
name,
save: () => null,
...get( serverSideBlockDefinitions, name ),
...settings,
};
Expand Down
21 changes: 12 additions & 9 deletions packages/blocks/src/api/test/registration.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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', () => {
Expand All @@ -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();
} );
} );
} );

Expand Down

0 comments on commit 4d65116

Please sign in to comment.