Successfully reported this slideshow.
Your SlideShare is downloading. ×

Custom gutenberg block development in react

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Loading in …3
×

Check these out next

1 of 71 Ad
Advertisement

More Related Content

Slideshows for you (20)

Similar to Custom gutenberg block development in react (20)

Advertisement

More from Imran Sayed (20)

Recently uploaded (20)

Advertisement

Custom gutenberg block development in react

  1. 1. Gutenberg Blocks Design Reuse Editing Experience
  2. 2. Ways of building Gutenberg Blocks ES 5 ESNext & JSX
  3. 3. Why write blocks in ES6/ESNext? Arrows Block Scoping Modules Classes Promises
  4. 4. ES5
  5. 5. ES5 ESNext
  6. 6. ES5 ESNext
  7. 7. Adding JSX What is JSX?
  8. 8. Adding JSX ● JavaScript XML ● A syntax that blends HTML and JavaScript. ● Provides syntactic sugar for the React.createElement() or wp.element.createElement() in Gutenberg.
  9. 9. JSX Example Type of Component
  10. 10. JSX Example Type of Component Lowercase letter: Built in component Capitalized: React Component
  11. 11. ES5 ESNext
  12. 12. ES5 ESNext + JSX
  13. 13. Why write blocks in ES6/ESNext? Easy to Read & Write Code
  14. 14. Why write blocks in ES6/ESNext? Prevents need for globals Shorter Syntax Functions
  15. 15. Why write blocks in ES6/ESNext? ● Simpler Code - Easy to read and write. ● Shorter Syntax using Arrow functions. ● Organize your code into smaller modules. ● Anticipate and prevent need of globals.
  16. 16. Why write blocks in ES6/ESNext? ● Block Scoping solves possible scoping ambiguity. ● Promises provide improved readability via methods chaining and succinct error handling
  17. 17. Challenges ● Requires an extra build step for code transformation. ● ES5 without JSX can run straight in the browser. ● Locating and understanding the compiled source code is difficult. ● Tooling around JavaScript could be intimidating.
  18. 18. Browser support
  19. 19. Solution @wordpress/scripts A collection of reusable scripts for WordPress Development.
  20. 20. Features of @wordpress/scripts ● Abstracts required libraries away to standardize and simplify development. ● Handles the dependencies and default configuration for webpack and Babel. ● Linting tools for JavaScript and Css. ● Code testing using jest. ● Check required licence and engines.
  21. 21. Block Development
  22. 22. Build blocks in 3 steps
  23. 23. 1.Installing Packages
  24. 24. Install packages with @wordpress/scripts mkdir custom-blocks cd custom-blocks npm init --yes npm i --save-dev @wordpress/scripts mkdir src touch index.php src/index.js src/editor.css src/style.css
  25. 25. Directory Structure ├── node_modules ├── package-lock.json ├── package.json └── src ├── editor.css ├── style.css └── index.js ├── index.php
  26. 26. Install packages with @wordpress/scripts Entry point : src/index.js Output: build/index.js ( enqueue this file )
  27. 27. Add scripts in package.json "scripts": { "build": "wp-scripts build", "start": "wp-scripts start" },
  28. 28. npm run start
  29. 29. Directory structure after build ├── build │ └── index.js ├── node_modules ├── package-lock.json ├── package.json └── src ├── editor.css ├── index.js └── style.css ├── index.php
  30. 30. Register Block Client Side
  31. 31. Register block client side const { __ } = wp.i18n; const { registerBlockType } = wp.blocks; registerBlockType( 'gtcb-blocks/custom-block', { key: value } ); Block name Block configuration object
  32. 32. Register block client side import { __ } from ‘@wordpress/i18n’; import { registerBlockType } from ’@wordpress/blocks’; registerBlockType( 'gtcb-blocks/custom-block', { title: __( 'Custom Block', 'custom-blocks' ), icon: 'megaphone', category: 'common', edit: () => ( <div>Hello World</div> ), save: () => ( <div>Hello World</div> ) } );
  33. 33. Edit function ● Describes the structure of the block ● Represents what the editor will render when the block is used on the editor. edit: () => ( <div>Hello World</div> ),
  34. 34. Save function ● Decides how your content would look at the front end. ● Defines how the attribute will combine together to generate a final mark-up. ● Mark up then serialized and saved into the database save: () => ( <div>Hello World</div> ),
  35. 35. Run the script
  36. 36. Directory structure after build ├── build │ └── index.js │ └── index.assets.php ├── node_modules ├── package-lock.json ├── package.json └── src ├── editor.css ├── index.js └── style.css ├── index.php
  37. 37. index.assets.php <?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-element', 'wp-i18n', 'wp-polyfill'), 'version' => '26c91f40469d04ed5d7bcff9ec3e126d');
  38. 38. Register Scripts & Styles /** * The 'enqueue_block_assets' hook includes styles and scripts both in editor and * frontend, except when is_admin() is used to include them conditionally */ add_action( 'enqueue_block_assets', 'enqueue_editor_assets' );
  39. 39. Register Scripts function enqueue_editor_assets() { $asset_config_file = sprintf( '%s/index.asset.php', GTCB_BUILD_PATH ); $asset_config = require_once $asset_config_file; wp_enqueue_script( 'gtcb-blocks-js', GTCB_BUILD_URI . '/index.js', $asset_config[‘dependencies’], $asset_config[‘version’], true ); }
  40. 40. Register styles ….. // Block editor styles. wp_register_style( 'gtcb-blocks-css', GTCB_BLOCKS_URL . '/src/style.css', [ 'wp-block-library-theme', 'wp-block-library', ], filemtime( GTCB_BLOCKS_PATH . '/src/editor.css' ) );
  41. 41. Dependencies ● wp-blocks : includes block type registration and related functions. ● wp-element : includes the WordPress Element abstraction for describing the structure of your blocks. ● wp-block-editor : includes components like RichText, MediaUpload etc
  42. 42. State of a Block
  43. 43. State ● A state is a plain JavaScript object. ● A state of a block is maintained through the editing session. ● To achieve dynamic change in the block’s structure when the user changes a block. ● Everytime a block is updated edit function is called.
  44. 44. Post saved in database <!-- wp:gtcb-blocks/custom-block --> <div class="wp-block-gtcb-blocks-custom-block" >Hello World</div> <!-- /wp:gtcb-blocks/custom-block --> Block name
  45. 45. Attributes
  46. 46. Attributes ● Help you extract block attribute values from saved post content. ● Map from the saved markup to a JavaScript representation of a block. ● Attribute sources are a superset of functionality provided by hpq
  47. 47. Attributes ● hpq: A small library used to parse and query HTML markup into an object shape. ● When you define these attributes into registerBlockType(), it is passed to the edit() and save()
  48. 48. Define Attributes registerBlockType( 'gtcb-blocks/custom-block', { ... attributes: { fullName: { type: 'array', source: 'children', selector: 'p' }, }, look for the text inside of selector
  49. 49. Attributes passed to edit() and save() edit: ( props ) => { console.log( props ); return ( <div>Hello World</div> ) }, save: ( props ) => { return ( <div>Hello World</div> ) },
  50. 50. Let’s console props attributes: fullName: [] className: "wp-block-gtcb-blocks-custom-block" name: "gtcb-blocks/custom-block" setAttributes: ƒ ()
  51. 51. Reusable Components
  52. 52. Reusable Components ● Instead of creating DOM nodes using createElement(), we can encapsulate this behavior using Components. ● Hide the complexity into their self-contained units ● Many blocks share the same complex behaviors ● Reusable Components simplify implementations of your block’s edit function ● RichText, BlockControls, AlignmentToolbar,
  53. 53. RichText
  54. 54. RichText Component import { RichText } from ‘@wordpress/block-editor’; registerBlockType( 'gtcb-blocks/custom-block', { ….
  55. 55. edit: ( props ) => { let { attributes: { fullName } , setAttributes, className } = props; return ( <RichText tagName="div" placeholder={ __( 'Full Name', 'custom-blocks' ) } value={ fullName } onChange={ ( value ) => setAttributes( { fullName: value } ) } className={ className } /> ) },
  56. 56. save: ( props ) => { let { attributes: { fullName } , className } = props; return ( <RichText.Content tagName="div" value={ fullName } className={ className } /> ) },
  57. 57. registerBlockType( 'gtcb-blocks/custom-block', { attributes: { fullName: { type: 'array', source: 'children', selector: 'div' }, }, edit: ( props ) => { let { attributes: { fullName } , setAttributes, className } = props; return ( <RichText tagName="div" placeholder={ __( 'Full Name', 'custom-blocks' ) } value={ fullName } onChange={ ( value ) => setAttributes( { fullName: value } ) } className={ className } /> ) }, save: ( props ) => { let { attributes: { fullName }, className } = props; return ( <RichText.Content tagName="div" value={ fullName } className={ className } /> )
  58. 58. User enters the data: edit ()
  59. 59. User saves the data: save ()
  60. 60. More Ways of building Blocks ● @wordpress/create-block
  61. 61. Third Party Libraries ● Editor Blocks ● Gutenberg Hub ● Gutenberg Cloud
  62. 62. WordPress Core for Gutenberg
  63. 63. Gutenberg Core ● registerBlockType() resides in https://github.com/WordPress/gutenberg/blob/master/ packages/blocks/src/api/registration.js. ● Components core files: https://github.com/WordPress/gutenberg/blob/master/ packages/block-editor/src/components/
  64. 64. Git repo ● Git repo for this example https://github.com/imranhsayed/custom-blocks ● Gutenberg Workshop https://github.com/imranhsayed/gutenberg-workshop
  65. 65. Questions?
  66. 66. Questions? Imran Sayed @imranhsayed

×