Using Blocks Outside The Editor

Using Blocks Outside The Editor

Eba4cc68bfbc2b59c3c3a3cf789075f0?s=128

Tom J Nowell

June 22, 2019
Tweet

Transcript

  1. @tarendai https://tomjn.com Using Blocks Outside The Editor

  2. @tarendai https://tomjn.com

  3. @tarendai https://tomjn.com Frontenberg https://frontenberg.tomjn.com

  4. @tarendai https://tomjn.com

  5. @tarendai https://tomjn.com Frontenberg Is not a frontend editor!

  6. @tarendai https://tomjn.com Blocks are the Interface

  7. @tarendai https://tomjn.com

  8. @tarendai https://tomjn.com wp.blocks.registerBlockType( 'tomjn/helloworld', { title: 'Hello World', icon: 'universal-access-alt',

    category: 'layout', edit() { return el("p", "Hello World, step 1 (from the editor)."); }, save() { return el("p", "Hello World, step 1 (from the frontend)"); }, } );
  9. @tarendai https://tomjn.com

  10. @tarendai https://tomjn.com

  11. @tarendai https://tomjn.com Building a Block Editor Component

  12. @tarendai https://tomjn.com function Editor({ startingContent, inputName }) { return <div

    className="editor-styles-wrapper"> .... </div>; }
  13. @tarendai https://tomjn.com function Editor({ startingContent, inputName }) { const [

    blocks, update ] = React.useState( parse(startingContent) ); return <div className="editor-styles-wrapper"> <BlockEditorProvider value={blocks} onInput={update} onChange={update}> <WritingFlow> <ObserveTyping> <BlockList /> </ObserveTyping> </WritingFlow> <Popover.Slot /> </BlockEditorProvider> <input type="hidden" name={inputName} value={serialize(blocks)} /> </div>; }
  14. @tarendai https://tomjn.com function Editor({ startingContent, inputName }) { const [

    blocks, update ] = React.useState( parse(startingContent) ); return <div className="editor-styles-wrapper"> <BlockEditorProvider value={blocks} onInput={update} onChange={update}> <WritingFlow> <ObserveTyping> <BlockList /> </ObserveTyping> </WritingFlow> <Popover.Slot /> </BlockEditorProvider> <input type="hidden" name={inputName} value={serialize(blocks)} /> </div>; }
  15. @tarendai https://tomjn.com function Editor({ startingContent, inputName }) { const [

    blocks, update ] = React.useState( parse(startingContent) ); return <div className="editor-styles-wrapper"> <BlockEditorProvider value={blocks} onInput={update} onChange={update}> <WritingFlow> <ObserveTyping> <BlockList /> </ObserveTyping> </WritingFlow> <Popover.Slot /> </BlockEditorProvider> <input type="hidden" name={inputName} value={serialize(blocks)} /> </div>; }
  16. @tarendai https://tomjn.com function Editor({ startingContent, inputName }) { const [

    blocks, update ] = React.useState( parse(startingContent) ); return <div className="editor-styles-wrapper"> <BlockEditorProvider value={blocks} onInput={update} onChange={update}> <WritingFlow> <ObserveTyping> <BlockList /> </ObserveTyping> </WritingFlow> <Popover.Slot /> </BlockEditorProvider> <input type="hidden" name={inputName} value={serialize(blocks)} /> </div>; }
  17. @tarendai https://tomjn.com function Editor({ startingContent, inputName }) { const [

    blocks, update ] = React.useState( parse(startingContent) ); return <div className="editor-styles-wrapper"> <BlockEditorProvider value={blocks} onInput={update} onChange={update}> <WritingFlow> <ObserveTyping> <BlockList /> </ObserveTyping> </WritingFlow> <Popover.Slot /> </BlockEditorProvider> <input type="hidden" name={inputName} value={serialize(blocks)} /> </div>; }
  18. @tarendai https://tomjn.com function Editor({ startingContent, inputName }) { const [

    blocks, update ] = React.useState( parse(startingContent) ); return <div className="editor-styles-wrapper"> <BlockEditorProvider value={blocks} onInput={update} onChange={update}> <WritingFlow> <ObserveTyping> <BlockList /> </ObserveTyping> </WritingFlow> <Popover.Slot /> </BlockEditorProvider> <input type="hidden" name={inputName} value={serialize(blocks)} /> </div>; }
  19. @tarendai https://tomjn.com

  20. @tarendai https://tomjn.com Building a Generic JS Function

  21. @tarendai https://tomjn.com tomjn_wp_editor( 'The ID of the tag', 'The desired

    input name', 'Starting content' );
  22. @tarendai https://tomjn.com

  23. @tarendai https://tomjn.com window.tomjn_wp_editor = function( id, inputName, content ) {

    const element = document.createElement( 'div' ); element.setAttribute( 'class', 'tomjn_editor_container block-editor gutenberg__editor' + 'block-editor__container' ); element.setAttribute( 'id', id ); document.getElementById( id ).replaceWith(element); ReactDOM.render( <Editor startingContent={content} inputName={inputName} />, element ); }
  24. @tarendai https://tomjn.com window.tomjn_wp_editor = function( id, inputName, content ) {

    const element = document.createElement( 'div' ); element.setAttribute( 'class', 'tomjn_editor_container block-editor gutenberg__editor' + 'block-editor__container' ); element.setAttribute( 'id', id ); document.getElementById( id ).replaceWith(element); ... }
  25. @tarendai https://tomjn.com ... ReactDOM.render( <Editor startingContent={content} inputName={inputName} />, element );

    }
  26. @tarendai https://tomjn.com Commenting

  27. @tarendai https://tomjn.com var allowedBlocks = [ 'core/paragraph', 'core/image', 'core/html', 'core/freeform'

    ]; wp.blocks.getBlockTypes().forEach( function( blockType ) { if ( allowedBlocks.indexOf( blockType.name ) === -1 ) { wp.blocks.unregisterBlockType( blockType.name ); } });
  28. @tarendai https://tomjn.com Building a Generic PHP function

  29. @tarendai https://tomjn.com

  30. @tarendai https://tomjn.com <?php wp_editor( $content, $editor_id, [] ); ?>

  31. @tarendai https://tomjn.com <?php wp_block_editor($content, $name); ?>

  32. @tarendai https://tomjn.com <?php function wp_block_editor( $content, $name ) { ?>

    <input name="<?php echo esc_attr( $name ); ?>" id="<?php echo esc_attr( $name ); ?>" type="hidden" /> <script> document.addEventListener('DOMContentLoaded', function(event) { tomjn_wp_editor( '<?php echo esc_js( $name ); ?>', '<?php echo esc_js( $name ); ?>', '<?php echo esc_js( $content ); ?>' ); }); </script> <?php }
  33. @tarendai https://tomjn.com Supporting PHP Code

  34. @tarendai https://tomjn.com 1. setup the core data layer 2. enqueue

    styles and scripts
  35. @tarendai https://tomjn.com $wp_scripts->registered['wp-data']->extra['after'] = array(); wp_add_inline_script( 'wp-data', implode( "\n", [

    '( function() {', ' var userId = ' . get_current_user_ID() . ';', ' var storageKey = "WP_DATA_USER_" + userId;', ' var persistence = wp.data.plugins.persistence', ' wp.data.use( persistence, { storageKey: storageKey } );', ' persistence.__unstableMigrate({ storageKey: storageKey });', ' wp.data.use( wp.data.plugins.controls );', '} )();', ]) );
  36. @tarendai https://tomjn.com wp_enqueue_script('wp-editor'); wp_enqueue_script('wp-core-data'); wp_enqueue_script('wp-data'); wp_enqueue_script('wp-block-library'); wp_enqueue_script('wp-format-library'); wp_enqueue_style('media'); wp_enqueue_style('l10n'); wp_enqueue_style('buttons');

    wp_enqueue_style('wp-editor');
  37. @tarendai https://tomjn.com I'm Tom J Nowell @tarendai https://tomjn.com WordPress VIP

  38. @tarendai https://tomjn.com https://wpvip.com/careers

  39. @tarendai https://tomjn.com

  40. @tarendai https://tomjn.com