From eeb5c0dcdb754544893b1b0989d711dd44798473 Mon Sep 17 00:00:00 2001 From: Marcus Kazmierczak Date: Fri, 12 Jun 2020 07:03:17 -0700 Subject: [PATCH 1/3] Move ESNext as default code example --- .../developers/richtext.md | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/docs/designers-developers/developers/richtext.md b/docs/designers-developers/developers/richtext.md index 29ceb06344d5f5..3909306a92d6d2 100644 --- a/docs/designers-developers/developers/richtext.md +++ b/docs/designers-developers/developers/richtext.md @@ -26,39 +26,6 @@ There are a number of core blocks using the RichText component. The JavaScript e ## Example {% codetabs %} -{% ES5 %} -```js -wp.blocks.registerBlockType( /* ... */, { - // ... - - attributes: { - content: { - type: 'string', - source: 'html', - selector: 'h2', - }, - }, - - edit: function( props ) { - return wp.element.createElement( wp.editor.RichText, { - tagName: 'h2', // The tag here is the element output and editable in the admin - className: props.className, - value: props.attributes.content, // Any existing content, either from the database or an attribute default - formattingControls: [ 'bold', 'italic' ], // Allow the content to be made bold or italic, but do not allow other formatting options - onChange: function( content ) { - props.setAttributes( { content: content } ); // Store updated content as a block attribute - }, - placeholder: __( 'Heading...' ), // Display this text before any content has been added by the user - } ); - }, - - save: function( props ) { - return wp.element.createElement( wp.editor.RichText.Content, { - tagName: 'h2', value: props.attributes.content // Saves

Content added in the editor...

to the database for frontend display - } ); - } -} ); -``` {% ESNext %} ```js import { registerBlockType } from '@wordpress/blocks'; @@ -93,6 +60,39 @@ registerBlockType( /* ... */, { } } ); ``` +{% ES5 %} +```js +wp.blocks.registerBlockType( /* ... */, { + // ... + + attributes: { + content: { + type: 'string', + source: 'html', + selector: 'h2', + }, + }, + + edit: function( props ) { + return wp.element.createElement( wp.editor.RichText, { + tagName: 'h2', // The tag here is the element output and editable in the admin + className: props.className, + value: props.attributes.content, // Any existing content, either from the database or an attribute default + formattingControls: [ 'bold', 'italic' ], // Allow the content to be made bold or italic, but do not allow other formatting options + onChange: function( content ) { + props.setAttributes( { content: content } ); // Store updated content as a block attribute + }, + placeholder: __( 'Heading...' ), // Display this text before any content has been added by the user + } ); + }, + + save: function( props ) { + return wp.element.createElement( wp.editor.RichText.Content, { + tagName: 'h2', value: props.attributes.content // Saves

Content added in the editor...

to the database for frontend display + } ); + } +} ); +``` {% end %} ## Common Issues & Solutions From 6a9a0064328625e42af6bc4f3e1a5dfbaaf8da2e Mon Sep 17 00:00:00 2001 From: Marcus Kazmierczak Date: Fri, 12 Jun 2020 07:18:32 -0700 Subject: [PATCH 2/3] Switch docs to ESNext first --- .../developers/block-api/block-attributes.md | 20 +- .../developers/block-api/block-deprecation.md | 132 +++++----- .../developers/block-api/block-edit-save.md | 234 +++++++++--------- .../developers/block-api/block-transforms.md | 133 ++++------ .../filters/autocomplete-filters.md | 60 ++--- .../developers/filters/block-filters.md | 90 ++++--- .../developers/internationalization.md | 48 ++-- 7 files changed, 343 insertions(+), 374 deletions(-) diff --git a/docs/designers-developers/developers/block-api/block-attributes.md b/docs/designers-developers/developers/block-api/block-attributes.md index 5d60dbc9306b7b..dd482fd49e5c95 100644 --- a/docs/designers-developers/developers/block-api/block-attributes.md +++ b/docs/designers-developers/developers/block-api/block-attributes.md @@ -185,6 +185,16 @@ attributes: { From here, meta attributes can be read and written by a block using the same interface as any attribute: {% codetabs %} +{% ESNext %} +```js +edit( { attributes, setAttributes } ) { + function onChange( event ) { + setAttributes( { author: event.target.value } ); + } + + return ; +}, +``` {% ES5 %} ```js edit: function( props ) { @@ -198,16 +208,6 @@ edit: function( props ) { } ); }, ``` -{% ESNext %} -```js -edit( { attributes, setAttributes } ) { - function onChange( event ) { - setAttributes( { author: event.target.value } ); - } - - return ; -}, -``` {% end %} ### Considerations diff --git a/docs/designers-developers/developers/block-api/block-deprecation.md b/docs/designers-developers/developers/block-api/block-deprecation.md index 067885f0708efd..ba1dd2f25b1f97 100644 --- a/docs/designers-developers/developers/block-api/block-deprecation.md +++ b/docs/designers-developers/developers/block-api/block-deprecation.md @@ -20,64 +20,64 @@ It's important to note that `attributes`, `supports`, and `save` are not automat ### Example: {% codetabs %} -{% ES5 %} +{% ESNext %} ```js -var el = wp.element.createElement, - registerBlockType = wp.blocks.registerBlockType, - attributes = { - text: { - type: 'string', - default: 'some random value', - } - }; +const { registerBlockType } = wp.blocks; +const attributes = { + text: { + type: 'string', + default: 'some random value', + } +}; registerBlockType( 'gutenberg/block-with-deprecated-version', { // ... other block properties go here - attributes: attributes, + attributes, - save: function( props ) { - return el( 'div', {}, props.attributes.text ); + save( props ) { + return
{ props.attributes.text }
; }, deprecated: [ { - attributes: attributes, + attributes, - save: function( props ) { - return el( 'p', {}, props.attributes.text ); + save( props ) { + return

{ props.attributes.text }

; }, } ] } ); ``` -{% ESNext %} +{% ES5 %} ```js -const { registerBlockType } = wp.blocks; -const attributes = { - text: { - type: 'string', - default: 'some random value', - } -}; +var el = wp.element.createElement, + registerBlockType = wp.blocks.registerBlockType, + attributes = { + text: { + type: 'string', + default: 'some random value', + } + }; registerBlockType( 'gutenberg/block-with-deprecated-version', { // ... other block properties go here - attributes, + attributes: attributes, - save( props ) { - return
{ props.attributes.text }
; + save: function( props ) { + return el( 'div', {}, props.attributes.text ); }, deprecated: [ { - attributes, + attributes: attributes, - save( props ) { - return

{ props.attributes.text }

; + save: function( props ) { + return el( 'p', {}, props.attributes.text ); }, } ] @@ -95,10 +95,9 @@ Sometimes, you need to update the attributes set to rename or modify old attribu ### Example: {% codetabs %} -{% ES5 %} +{% ESNext %} ```js -var el = wp.element.createElement, - registerBlockType = wp.blocks.registerBlockType; +const { registerBlockType } = wp.blocks; registerBlockType( 'gutenberg/block-with-deprecated-version', { @@ -111,8 +110,8 @@ registerBlockType( 'gutenberg/block-with-deprecated-version', { } }, - save: function( props ) { - return el( 'div', {}, props.attributes.content ); + save( props ) { + return
{ props.attributes.content }
; }, deprecated: [ @@ -124,22 +123,23 @@ registerBlockType( 'gutenberg/block-with-deprecated-version', { } }, - migrate: function( attributes ) { + migrate( { text } ) { return { - content: attributes.text + content: text }; }, - save: function( props ) { - return el( 'p', {}, props.attributes.text ); + save( props ) { + return

{ props.attributes.text }

; }, } ] } ); ``` -{% ESNext %} +{% ES5 %} ```js -const { registerBlockType } = wp.blocks; +var el = wp.element.createElement, + registerBlockType = wp.blocks.registerBlockType; registerBlockType( 'gutenberg/block-with-deprecated-version', { @@ -152,8 +152,8 @@ registerBlockType( 'gutenberg/block-with-deprecated-version', { } }, - save( props ) { - return
{ props.attributes.content }
; + save: function( props ) { + return el( 'div', {}, props.attributes.content ); }, deprecated: [ @@ -165,14 +165,14 @@ registerBlockType( 'gutenberg/block-with-deprecated-version', { } }, - migrate( { text } ) { + migrate: function( attributes ) { return { - content: text + content: attributes.text }; }, - save( props ) { - return

{ props.attributes.text }

; + save: function( props ) { + return el( 'p', {}, props.attributes.text ); }, } ] @@ -191,16 +191,19 @@ E.g: a block wants to migrate a title attribute to a paragraph innerBlock. ### Example: {% codetabs %} -{% ES5 %} +{% ESNext %} ```js -var el = wp.element.createElement, - registerBlockType = wp.blocks.registerBlockType, - omit = lodash.omit; +const { registerBlockType } = wp.blocks; +const { omit } = lodash; registerBlockType( 'gutenberg/block-with-deprecated-version', { // ... block properties go here + save( props ) { + return

{ props.attributes.title }

; + }, + deprecated: [ { attributes: { @@ -211,7 +214,7 @@ registerBlockType( 'gutenberg/block-with-deprecated-version', { }, }, - migrate: function( attributes, innerBlocks ) { + migrate( attributes, innerBlocks ) { return [ omit( attributes, 'title' ), [ @@ -219,30 +222,28 @@ registerBlockType( 'gutenberg/block-with-deprecated-version', { content: attributes.title, fontSize: 'large', } ), - ].concat( innerBlocks ), + ...innerBlocks, + ], ]; }, - save: function( props ) { - return el( 'p', {}, props.attributes.title ); + save( props ) { + return

{ props.attributes.title }

; }, } ] } ); ``` -{% ESNext %} +{% ES5 %} ```js -const { registerBlockType } = wp.blocks; -const { omit } = lodash; +var el = wp.element.createElement, + registerBlockType = wp.blocks.registerBlockType, + omit = lodash.omit; registerBlockType( 'gutenberg/block-with-deprecated-version', { // ... block properties go here - save( props ) { - return

{ props.attributes.title }

; - }, - deprecated: [ { attributes: { @@ -253,7 +254,7 @@ registerBlockType( 'gutenberg/block-with-deprecated-version', { }, }, - migrate( attributes, innerBlocks ) { + migrate: function( attributes, innerBlocks ) { return [ omit( attributes, 'title' ), [ @@ -261,13 +262,12 @@ registerBlockType( 'gutenberg/block-with-deprecated-version', { content: attributes.title, fontSize: 'large', } ), - ...innerBlocks, - ], + ].concat( innerBlocks ), ]; }, - save( props ) { - return

{ props.attributes.title }

; + save: function( props ) { + return el( 'p', {}, props.attributes.title ); }, } ] 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 5d0cc72b6c6b78..08689ee8fd9961 100644 --- a/docs/designers-developers/developers/block-api/block-edit-save.md +++ b/docs/designers-developers/developers/block-api/block-edit-save.md @@ -7,6 +7,12 @@ When registering a block, the `edit` and `save` functions provide the interface 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. {% codetabs %} +{% ESNext %} +```jsx +edit: () => { + return
Your block.
; +} +``` {% ES5 %} ```js // A static div @@ -18,12 +24,6 @@ edit: function() { ); } ``` -{% ESNext %} -```jsx -edit: () => { - return
Your block.
; -} -``` {% end %} The function receives the following properties through an object argument: @@ -35,6 +35,12 @@ This property surfaces all the available attributes and their corresponding valu In this case, assuming we had defined an attribute of `content` during block registration, we would receive and use that value in our edit function: {% codetabs %} +{% ESNext %} +```js +edit: ( { attributes } ) => { + return
{ attributes.content }
; +} +``` {% ES5 %} ```js edit: function( props ) { @@ -45,12 +51,6 @@ edit: function( props ) { ); } ``` -{% ESNext %} -```js -edit: ( { attributes } ) => { - return
{ attributes.content }
; -} -``` {% end %} The value of `attributes.content` will be displayed inside the `div` when inserting the block in the editor. @@ -60,6 +60,12 @@ The value of `attributes.content` will be displayed inside the `div` when insert This property returns the class name for the wrapper element. This is automatically added in the `save` method, but not on `edit`, as the root element may not correspond to what is _visually_ the main element of the block. You can request it to add it to the correct element in your function. {% codetabs %} +{% ESNext %} +```js +edit: ( { attributes, className } ) => { + return
{ attributes.content }
; +} +``` {% ES5 %} ```js edit: function( props ) { @@ -70,12 +76,6 @@ edit: function( props ) { ); } ``` -{% ESNext %} -```js -edit: ( { attributes, className } ) => { - return
{ attributes.content }
; -} -``` {% end %} ### isSelected @@ -83,6 +83,19 @@ edit: ( { attributes, className } ) => { The isSelected property is an object that communicates whether the block is currently selected. {% codetabs %} +{% ESNext %} +```jsx +edit: ( { attributes, className, isSelected } ) => { + return ( +
+ Your block. + { isSelected && + Shows only when the block is selected. + } +
+ ); +} +``` {% ES5 %} ```js edit: function( props ) { @@ -100,26 +113,31 @@ edit: function( props ) { ); } ``` +{% end %} + +### setAttributes + +This function allows the block to update individual attributes based on user interactions. + +{% codetabs %} {% ESNext %} ```jsx -edit: ( { attributes, className, isSelected } ) => { +edit: ( { attributes, setAttributes, className, isSelected } ) => { + // Simplify access to attributes + const { content, mySetting } = attributes; + + // Toggle a setting when the user clicks the button + const toggleSetting = () => setAttributes( { mySetting: ! mySetting } ); return (
- Your block. + { content } { isSelected && - Shows only when the block is selected. + }
); } ``` -{% end %} - -### setAttributes - -This function allows the block to update individual attributes based on user interactions. - -{% codetabs %} {% ES5 %} ```js edit: function( props ) { @@ -143,29 +161,24 @@ edit: function( props ) { ); }, ``` -{% ESNext %} -```jsx -edit: ( { attributes, setAttributes, className, isSelected } ) => { - // Simplify access to attributes - const { content, mySetting } = attributes; - - // Toggle a setting when the user clicks the button - const toggleSetting = () => setAttributes( { mySetting: ! mySetting } ); - return ( -
- { content } - { isSelected && - - } -
- ); -} -``` {% end %} When using attributes that are objects or arrays it's a good idea to copy or clone the attribute prior to updating it: {% codetabs %} +{% ESNext %} +```js +// Good - a new array is created from the old list attribute and a new list item: +const { list } = attributes; +const addListItem = ( newListItem ) => setAttributes( { list: [ ...list, newListItem ] } ); + +// Bad - the list from the existing attribute is modified directly to add the new list item: +const { list } = attributes; +const addListItem = ( newListItem ) => { + list.push( newListItem ); + setAttributes( { list } ); +}; +``` {% ES5 %} ```js // Good - cloning the old list @@ -182,19 +195,6 @@ var addListItem = function( newListItem ) { setAttributes( { list: list } ); }; ``` -{% ESNext %} -```js -// Good - a new array is created from the old list attribute and a new list item: -const { list } = attributes; -const addListItem = ( newListItem ) => setAttributes( { list: [ ...list, newListItem ] } ); - -// Bad - the list from the existing attribute is modified directly to add the new list item: -const { list } = attributes; -const addListItem = ( newListItem ) => { - list.push( newListItem ); - setAttributes( { list } ); -}; -``` {% end %} Why do this? In JavaScript, arrays and objects are passed by reference, so this practice ensures changes won't affect other code that might hold references to the same data. Furthermore, the Gutenberg project follows the philosophy of the Redux library that [state should be immutable](https://redux.js.org/faq/immutable-data#what-are-the-benefits-of-immutability)—data should not be changed directly, but instead a new version of the data created containing the changes. @@ -204,6 +204,12 @@ Why do this? In JavaScript, arrays and objects are passed by reference, so this The `save` function defines the way in which the different attributes should be combined into the final markup, which is then serialized into `post_content`. {% codetabs %} +{% ESNext %} +```jsx +save: () => { + return
Your block.
; +} +``` {% ES5 %} ```js save: function() { @@ -214,12 +220,6 @@ save: function() { ); } ``` -{% ESNext %} -```jsx -save: () => { - return
Your block.
; -} -``` {% end %} For most blocks, the return value of `save` should be an [instance of WordPress Element](/packages/element/README.md) representing how the block is to appear on the front of the site. @@ -242,6 +242,12 @@ If left unspecified, the default implementation will save no markup in post cont As with `edit`, the `save` function also receives an object argument including attributes which can be inserted into the markup. {% codetabs %} +{% ESNext %} +```jsx +save: ( { attributes } ) => { + return
{ attributes.content }
; +} +``` {% ES5 %} ```js save: function( props ) { @@ -252,12 +258,6 @@ save: function( props ) { ); } ``` -{% ESNext %} -```jsx -save: ( { attributes } ) => { - return
{ attributes.content }
; -} -``` {% end %} @@ -270,6 +270,31 @@ Here are a couple examples of using attributes, edit, and save all together. Fo ### Saving Attributes to Child Elements {% codetabs %} +{% ESNext %} +```jsx +attributes: { + content: { + type: 'string', + source: 'html', + selector: 'p' + } +}, + +edit: ( { attributes, setAttributes } ) => { + const updateFieldValue = ( val ) => { + setAttributes( { content: val } ); + } + return ; +}, + +save: ( { attributes } ) => { + return

{ attributes.content }

; +}, +``` {% ES5 %} ```js attributes: { @@ -299,40 +324,38 @@ save: function( props ) { return el( 'p', {}, props.attributes.content ); }, ``` +{% end %} + +### Saving Attributes via Serialization + +Ideally, the attributes saved should be included in the markup. However, there are times when this is not practical, so if no attribute source is specified the attribute is serialized and saved to the block's comment delimiter. + +This example could be for a dynamic block, such as the [Latest Posts block](https://github.com/WordPress/gutenberg/blob/master/packages/block-library/src/latest-posts/index.js), which renders the markup server-side. The save function is still required, however in this case it simply returns null since the block is not saving content from the editor. + +{% codetabs %} {% ESNext %} ```jsx attributes: { - content: { - type: 'string', - source: 'html', - selector: 'p' + postsToShow: { + type: 'number', } }, edit: ( { attributes, setAttributes } ) => { - const updateFieldValue = ( val ) => { - setAttributes( { content: val } ); - } return ; + label='Number Posts to Show' + value={ attributes.postsToShow } + onChange={ ( val ) => { + setAttributes( { postsToShow: parseInt( val ) } ); + }}, + } + ); }, -save: ( { attributes } ) => { - return

{ attributes.content }

; -}, +save: () => { + return null; +} ``` -{% end %} - -### Saving Attributes via Serialization - -Ideally, the attributes saved should be included in the markup. However, there are times when this is not practical, so if no attribute source is specified the attribute is serialized and saved to the block's comment delimiter. - -This example could be for a dynamic block, such as the [Latest Posts block](https://github.com/WordPress/gutenberg/blob/master/packages/block-library/src/latest-posts/index.js), which renders the markup server-side. The save function is still required, however in this case it simply returns null since the block is not saving content from the editor. - -{% codetabs %} {% ES5 %} ```js attributes: { @@ -358,29 +381,6 @@ save: function() { return null; } ``` -{% ESNext %} -```jsx -attributes: { - postsToShow: { - type: 'number', - } -}, - -edit: ( { attributes, setAttributes } ) => { - return { - setAttributes( { postsToShow: parseInt( val ) } ); - }}, - } - ); -}, - -save: () => { - return null; -} -``` {% end %} diff --git a/docs/designers-developers/developers/block-api/block-transforms.md b/docs/designers-developers/developers/block-api/block-transforms.md index cd3a88e2be252e..9f4346c2600e31 100644 --- a/docs/designers-developers/developers/block-api/block-transforms.md +++ b/docs/designers-developers/developers/block-api/block-transforms.md @@ -46,42 +46,38 @@ A transformation of type `block` is an object that takes the following parameter To declare this transformation we add the following code into the heading block configuration, which uses the `createBlock` function from the [`wp-blocks` package](/packages/blocks/README.md#createBlock). {% codetabs %} -{% ES5 %} - +{% ESNext %} ```js transforms: { from: [ { type: 'block', blocks: [ 'core/paragraph' ], - transform: function ( attributes ) { + transform: ( { content } ) => { return createBlock( 'core/heading', { - content: attributes.content, + content, } ); }, }, ] }, ``` - -{% ESNext %} - +{% ES5 %} ```js transforms: { from: [ { type: 'block', blocks: [ 'core/paragraph' ], - transform: ( { content } ) => { + transform: function ( attributes ) { return createBlock( 'core/heading', { - content, + content: attributes.content, } ); }, }, ] }, ``` - {% end %} **Example: blocks that have InnerBlocks** @@ -89,15 +85,14 @@ transforms: { A block with InnerBlocks can also be transformed from and to another block with InnerBlocks. {% codetabs %} -{% ES5 %} - +{% ESNext %} ```js transforms: { to: [ { type: 'block', blocks: [ 'some/block-with-innerblocks' ], - transform: function( attributes, innerBlocks ) { + transform: ( attributes, innerBlocks ) => { return createBlock( 'some/other-block-with-innerblocks', attributes, @@ -108,16 +103,14 @@ transforms: { ], }, ``` - -{% ESNext %} - +{% ES5 %} ```js transforms: { to: [ { type: 'block', blocks: [ 'some/block-with-innerblocks' ], - transform: ( attributes, innerBlocks ) => { + transform: function( attributes, innerBlocks ) { return createBlock( 'some/other-block-with-innerblocks', attributes, @@ -128,7 +121,6 @@ transforms: { ], }, ``` - {% end %} ### Enter @@ -147,37 +139,32 @@ A transformation of type `enter` is an object that takes the following parameter To create a separator block when the user types the hypen three times and then hits the ENTER key we can use the following code: {% codetabs %} - -{% ES5 %} - +{% ESNext %} ```js transforms = { from: [ { type: 'enter', regExp: /^-{3,}$/, - transform: function( value ) { - return createBlock( 'core/separator' ); - }, + transform: () => createBlock( 'core/separator' ), }, ] } ``` - -{% ESNext %} - +{% ES5 %} ```js transforms = { from: [ { type: 'enter', regExp: /^-{3,}$/, - transform: () => createBlock( 'core/separator' ), + transform: function( value ) { + return createBlock( 'core/separator' ); + }, }, ] } ``` - {% end %} ### Files @@ -196,23 +183,20 @@ A transformation of type `files` is an object that takes the following parameter To create a File block when the user drops a file into the editor we can use the following code: {% codetabs %} -{% ES5 %} - +{% ESNext %} ```js transforms: { from: [ { type: 'files', - isMatch: function( files ) { - return files.length === 1; - }, + isMatch: ( files ) => files.length === 1, // By defining a lower priority than the default of 10, // we make that the File block to be created as a fallback, // if no other transform is found. priority: 15, - transform: function( files ) { - var file = files[ 0 ]; - var blobURL = createBlobURL( file ); + transform: ( files ) => { + const file = files[ 0 ]; + const blobURL = createBlobURL( file ); // File will be uploaded in componentDidMount() return createBlock( 'core/file', { href: blobURL, @@ -224,22 +208,22 @@ transforms: { ]; } ``` - -{% ESNext %} - +{% ES5 %} ```js transforms: { from: [ { type: 'files', - isMatch: ( files ) => files.length === 1, + isMatch: function( files ) { + return files.length === 1; + }, // By defining a lower priority than the default of 10, // we make that the File block to be created as a fallback, // if no other transform is found. priority: 15, - transform: ( files ) => { - const file = files[ 0 ]; - const blobURL = createBlobURL( file ); + transform: function( files ) { + var file = files[ 0 ]; + var blobURL = createBlobURL( file ); // File will be uploaded in componentDidMount() return createBlock( 'core/file', { href: blobURL, @@ -251,7 +235,6 @@ transforms: { ]; } ``` - {% end %} ### Prefix @@ -270,15 +253,14 @@ A transformation of type `prefix` is an object that takes the following paramete If we want to create a custom block when the user types the question mark, we could use this code: {% codetabs %} -{% ES5 %} - +{% ESNext %} ```js transforms: { from: [ { type: 'prefix', prefix: '?', - transform: function( content ) { + transform( content ) { return createBlock( 'my-plugin/question', { content, } ); @@ -287,16 +269,14 @@ transforms: { ]; } ``` - -{% ESNext %} - +{% ES5 %} ```js transforms: { from: [ { type: 'prefix', prefix: '?', - transform( content ) { + transform: function( content ) { return createBlock( 'my-plugin/question', { content, } ); @@ -305,7 +285,6 @@ transforms: { ]; } ``` - {% end %} ### Raw @@ -326,18 +305,16 @@ A transformation of type `raw` is an object that takes the following parameters: If we want to create an Embed block when the user pastes some URL in the editor, we could use this code: {% codetabs %} -{% ES5 %} - +{% ESNext %} ```js transforms: { from: [ { type: 'raw', - isMatch: function( node ) { - return node.nodeName === 'P' && - /^\s*(https?:\/\/\S+)\s*$/i.test( node.textContent ); - }, - transform: function( node ) { + isMatch: ( node ) => + node.nodeName === 'P' && + /^\s*(https?:\/\/\S+)\s*$/i.test( node.textContent ), + transform: ( node ) => { return createBlock( 'core/embed', { url: node.textContent.trim(), } ); @@ -346,18 +323,17 @@ transforms: { ], } ``` - -{% ESNext %} - +{% ES5 %} ```js transforms: { from: [ { type: 'raw', - isMatch: ( node ) => - node.nodeName === 'P' && - /^\s*(https?:\/\/\S+)\s*$/i.test( node.textContent ), - transform: ( node ) => { + isMatch: function( node ) { + return node.nodeName === 'P' && + /^\s*(https?:\/\/\S+)\s*$/i.test( node.textContent ); + }, + transform: function( node ) { return createBlock( 'core/embed', { url: node.textContent.trim(), } ); @@ -366,7 +342,6 @@ transforms: { ], } ``` - {% end %} ### Shortcode @@ -386,8 +361,7 @@ A transformation of type `shortcode` is an object that takes the following param An existing shortcode can be transformed into its block counterpart. {% codetabs %} -{% ES5 %} - +{% ESNext %} ```js transforms: { from: [ @@ -406,8 +380,7 @@ transforms: { // The shortcode function will extract // the shortcode atts into a value // to be sourced in the block's comment. - shortcode: function( attributes ) { - var align = attributes.named.align ? attributes.named.align : 'alignnone'; + shortcode: ( { named: { align = 'alignnone' } } ) => { return align.replace( 'align', '' ); }, }, @@ -415,16 +388,14 @@ transforms: { // Prevent the shortcode to be converted // into this block when it doesn't // have the proper ID. - isMatch: function( attributes ) { - return attributes.named.id === 'my-id'; + isMatch( { named: { id } } ) { + return id === 'my-id'; }, }, ] }, ``` - -{% ESNext %} - +{% ES5 %} ```js transforms: { from: [ @@ -443,7 +414,8 @@ transforms: { // The shortcode function will extract // the shortcode atts into a value // to be sourced in the block's comment. - shortcode: ( { named: { align = 'alignnone' } } ) => { + shortcode: function( attributes ) { + var align = attributes.named.align ? attributes.named.align : 'alignnone'; return align.replace( 'align', '' ); }, }, @@ -451,12 +423,11 @@ transforms: { // Prevent the shortcode to be converted // into this block when it doesn't // have the proper ID. - isMatch( { named: { id } } ) { - return id === 'my-id'; + isMatch: function( attributes ) { + return attributes.named.id === 'my-id'; }, }, ] }, ``` - {% end %} diff --git a/docs/designers-developers/developers/filters/autocomplete-filters.md b/docs/designers-developers/developers/filters/autocomplete-filters.md index 1707080e867e8c..584e2019a1d178 100644 --- a/docs/designers-developers/developers/filters/autocomplete-filters.md +++ b/docs/designers-developers/developers/filters/autocomplete-filters.md @@ -9,10 +9,10 @@ The `Autocomplete` component found in `@wordpress/block-editor` applies this fil Here is an example of using the `editor.Autocomplete.completers` filter to add an acronym completer. You can find full documentation for the autocompleter interface with the `Autocomplete` component in the `@wordpress/components` package. {% codetabs %} -{% ES5 %} -```js +{% ESNext %} +```jsx // Our completer -var acronymCompleter = { +const acronymCompleter = { name: 'acronyms', triggerPrefix: '::', options: [ @@ -20,40 +20,34 @@ var acronymCompleter = { { letters: 'AFAIK', expansion: 'As Far As I Know' }, { letters: 'IIRC', expansion: 'If I Recall Correctly' }, ], - getOptionKeywords: function( abbr ) { - var expansionWords = abbr.expansion.split( /\s+/ ); - return [ abbr.letters ].concat( expansionWords ); - }, - getOptionLabel: function( acronym ) { - return acronym.letters; - }, - getOptionCompletion: function( abbr ) { - return wp.element.createElement( - 'abbr', - { title: abbr.expansion }, - abbr.letters - ); + getOptionKeywords( { letters, expansion } ) { + const expansionWords = expansion.split( /\s+/ ); + return [ letters, ...expansionWords ]; }, + getOptionLabel: acronym => acronym.letters, + getOptionCompletion: ( { letters, expansion } ) => ( + { letters }, + ), }; // Our filter function function appendAcronymCompleter( completers, blockName ) { return blockName === 'my-plugin/foo' ? - completers.concat( acronymCompleter ) : + [ ...completers, acronymCompleter ] : completers; } // Adding the filter wp.hooks.addFilter( 'editor.Autocomplete.completers', - 'my-plugin/autocompleters/acronyms', + 'my-plugin/autocompleters/acronym', appendAcronymCompleter ); ``` -{% ESNext %} -```jsx +{% ES5 %} +```js // Our completer -const acronymCompleter = { +var acronymCompleter = { name: 'acronyms', triggerPrefix: '::', options: [ @@ -61,27 +55,33 @@ const acronymCompleter = { { letters: 'AFAIK', expansion: 'As Far As I Know' }, { letters: 'IIRC', expansion: 'If I Recall Correctly' }, ], - getOptionKeywords( { letters, expansion } ) { - const expansionWords = expansion.split( /\s+/ ); - return [ letters, ...expansionWords ]; + getOptionKeywords: function( abbr ) { + var expansionWords = abbr.expansion.split( /\s+/ ); + return [ abbr.letters ].concat( expansionWords ); + }, + getOptionLabel: function( acronym ) { + return acronym.letters; + }, + getOptionCompletion: function( abbr ) { + return wp.element.createElement( + 'abbr', + { title: abbr.expansion }, + abbr.letters + ); }, - getOptionLabel: acronym => acronym.letters, - getOptionCompletion: ( { letters, expansion } ) => ( - { letters }, - ), }; // Our filter function function appendAcronymCompleter( completers, blockName ) { return blockName === 'my-plugin/foo' ? - [ ...completers, acronymCompleter ] : + completers.concat( acronymCompleter ) : completers; } // Adding the filter wp.hooks.addFilter( 'editor.Autocomplete.completers', - 'my-plugin/autocompleters/acronym', + 'my-plugin/autocompleters/acronyms', appendAcronymCompleter ); ``` diff --git a/docs/designers-developers/developers/filters/block-filters.md b/docs/designers-developers/developers/filters/block-filters.md index 15c1cadc3fc2aa..7c12174e10e6bf 100644 --- a/docs/designers-developers/developers/filters/block-filters.md +++ b/docs/designers-developers/developers/filters/block-filters.md @@ -221,6 +221,30 @@ Used to modify the block's `edit` component. It receives the original block `Blo _Example:_ {% codetabs %} +{% ESNext %} +```js +const { createHigherOrderComponent } = wp.compose; +const { Fragment } = wp.element; +const { InspectorControls } = wp.blockEditor; +const { PanelBody } = wp.components; + +const withInspectorControls = createHigherOrderComponent( ( BlockEdit ) => { + return ( props ) => { + return ( + + + + + My custom control + + + + ); + }; +}, "withInspectorControl" ); + +wp.hooks.addFilter( 'editor.BlockEdit', 'my-plugin/with-inspector-controls', withInspectorControls ); +``` {% ES5 %} ```js var el = wp.element.createElement; @@ -247,30 +271,6 @@ var withInspectorControls = wp.compose.createHigherOrderComponent( function( Blo }; }, 'withInspectorControls' ); -wp.hooks.addFilter( 'editor.BlockEdit', 'my-plugin/with-inspector-controls', withInspectorControls ); -``` -{% ESNext %} -```js -const { createHigherOrderComponent } = wp.compose; -const { Fragment } = wp.element; -const { InspectorControls } = wp.blockEditor; -const { PanelBody } = wp.components; - -const withInspectorControls = createHigherOrderComponent( ( BlockEdit ) => { - return ( props ) => { - return ( - - - - - My custom control - - - - ); - }; -}, "withInspectorControl" ); - wp.hooks.addFilter( 'editor.BlockEdit', 'my-plugin/with-inspector-controls', withInspectorControls ); ``` {% end %} @@ -282,8 +282,19 @@ Used to modify the block's wrapper component containing the block's `edit` compo _Example:_ {% codetabs %} -{% ES5 %} +{% ESNext %} +```js +const { createHigherOrderComponent } = wp.compose; +const withClientIdClassName = createHigherOrderComponent( ( BlockListBlock ) => { + return ( props ) => { + return ; + }; +}, 'withClientIdClassName' ); + +wp.hooks.addFilter( 'editor.BlockListBlock', 'my-plugin/with-client-id-class-name', withClientIdClassName ); +``` +{% ES5 %} ```js var el = wp.element.createElement; @@ -305,21 +316,7 @@ var withClientIdClassName = wp.compose.createHigherOrderComponent( function( Blo }, 'withClientIdClassName' ); wp.hooks.addFilter( 'editor.BlockListBlock', 'my-plugin/with-client-id-class-name', withClientIdClassName ); - ``` -{% ESNext %} -```js -const { createHigherOrderComponent } = wp.compose; - -const withClientIdClassName = createHigherOrderComponent( ( BlockListBlock ) => { - return ( props ) => { - return ; - }; -}, 'withClientIdClassName' ); - -wp.hooks.addFilter( 'editor.BlockListBlock', 'my-plugin/with-client-id-class-name', withClientIdClassName ); -``` - {% end %} ## Removing Blocks @@ -329,13 +326,6 @@ wp.hooks.addFilter( 'editor.BlockListBlock', 'my-plugin/with-client-id-class-nam Adding blocks is easy enough, removing them is as easy. Plugin or theme authors have the possibility to "unregister" blocks. {% codetabs %} -{% ES5 %} -```js -// my-plugin.js -wp.domReady( function() { - wp.blocks.unregisterBlockType( 'core/verse' ); -} ); -``` {% ESNext %} ```js // my-plugin.js @@ -346,6 +336,13 @@ domReady( function() { unregisterBlockType( 'core/verse' ); } ); ``` +{% ES5 %} +```js +// my-plugin.js +wp.domReady( function() { + wp.blocks.unregisterBlockType( 'core/verse' ); +} ); +``` {% end %} and load this script in the Editor @@ -436,6 +433,7 @@ You can also display an icon with your block category by setting an `icon` attri You can also set a custom icon in SVG format. To do so, the icon should be rendered and set on the frontend, so it can make use of WordPress SVG, allowing mobile compatibility and making the icon more accessible. To set an SVG icon for the category shown in the previous example, add the following example JavaScript code to the editor calling `wp.blocks.updateCategory` e.g: + ```js ( function() { var el = wp.element.createElement; diff --git a/docs/designers-developers/developers/internationalization.md b/docs/designers-developers/developers/internationalization.md index 1f0815ee2d246c..90e59456c60071 100644 --- a/docs/designers-developers/developers/internationalization.md +++ b/docs/designers-developers/developers/internationalization.md @@ -34,58 +34,58 @@ function myguten_block_init() { add_action( 'init', 'myguten_block_init' ); ``` -In your code, you can include the i18n functions. The most common function is **__** (a double underscore) which provides translation of a simple string. Here is a basic static block example, this is in a file called `block.js`: +In your code, you can include the i18n functions. The most common function is **__** (a double underscore) which provides translation of a simple string. Here is a basic block example: {% codetabs %} -{% ES5 %} +{% ESNext %} ```js -const { __ } = wp.i18n; -const el = wp.element.createElement; -const { registerBlockType } = wp.blocks; +import { __ } from '@wordpress/i18n'; +import { registerBlockType } from '@wordpress/blocks'; registerBlockType( 'myguten/simple', { title: __( 'Simple Block', 'myguten' ), category: 'widgets', edit: () => { - return el( - 'p', - { style: { color: 'red' } }, - __( 'Hello World', 'myguten' ) + return ( +

+ { __( 'Hello World', 'myguten' ) } +

); }, save: () => { - return el( - 'p', - { style: { color: 'red' } }, - __( 'Hello World', 'myguten' ) + return ( +

+ { __( 'Hello World', 'myguten' ) } +

); }, } ); ``` -{% ESNext %} +{% ES5 %} ```js -import { __ } from '@wordpress/i18n'; -import { registerBlockType } from '@wordpress/blocks'; +const { __ } = wp.i18n; +const el = wp.element.createElement; +const { registerBlockType } = wp.blocks; registerBlockType( 'myguten/simple', { title: __( 'Simple Block', 'myguten' ), category: 'widgets', edit: () => { - return ( -

- { __( 'Hello World', 'myguten' ) } -

+ return el( + 'p', + { style: { color: 'red' } }, + __( 'Hello World', 'myguten' ) ); }, save: () => { - return ( -

- { __( 'Hello World', 'myguten' ) } -

+ return el( + 'p', + { style: { color: 'red' } }, + __( 'Hello World', 'myguten' ) ); }, } ); From 3bf4de8974090dc6c2ec55a5b1bf2dd505e71f7f Mon Sep 17 00:00:00 2001 From: Marcus Kazmierczak Date: Fri, 12 Jun 2020 08:52:17 -0700 Subject: [PATCH 3/3] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Andrés --- docs/designers-developers/developers/internationalization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/designers-developers/developers/internationalization.md b/docs/designers-developers/developers/internationalization.md index 90e59456c60071..bc97e97f48348b 100644 --- a/docs/designers-developers/developers/internationalization.md +++ b/docs/designers-developers/developers/internationalization.md @@ -73,7 +73,7 @@ registerBlockType( 'myguten/simple', { title: __( 'Simple Block', 'myguten' ), category: 'widgets', - edit: () => { + edit: function() { return el( 'p', { style: { color: 'red' } }, @@ -81,7 +81,7 @@ registerBlockType( 'myguten/simple', { ); }, - save: () => { + save: function() { return el( 'p', { style: { color: 'red' } },