Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Using Blocks Outside The Editor
Search
Tom J Nowell
June 22, 2019
Technology
1.2k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Using Blocks Outside The Editor
Tom J Nowell
June 22, 2019
More Decks by Tom J Nowell
See All by Tom J Nowell
Composer_and_WordPress__1_.pdf
tarendai
0
97
REST APIs for Absolute Beginners
tarendai
0
1k
VVV 2
tarendai
0
890
WordCamp Europe 2016 - Handling Anxiety
tarendai
1
590
Escape From New York
tarendai
0
820
WP The Right Way
tarendai
0
1.1k
Code Deodorant 2014
tarendai
1
830
Adv WP CLI
tarendai
0
790
WP CLI
tarendai
0
750
Other Decks in Technology
See All in Technology
20260804_Q4AzureUpdateBite_FabricDataAgentの精度を高める設計.pdf
matayuuu
1
120
Sansan Engineering Unit 紹介資料
sansan33
PRO
1
4.9k
toio・myCobotでフィジカルAIっぽいことを行うための検討(とりあえず調査) / フィジカルAI LT(IoTLTによる開催)
you
PRO
0
300
社内の7割が使うデータ基盤を、 データチーム2人で回すためにやったこと
koh_yoshi
4
1.2k
研究開発部の紹介 / Sansan R&D Profile
sansan33
PRO
4
24k
ボトムアップ文化が強い組織で セキュリティをどう根付かせていくかの現在進行形の話 / Making Security Stick in a Bottom-Up Organization
yamaguchitk333
0
210
PLATEAU で バーチャル花火大会
tatsuya1970
0
110
ホームラボ紹介
y_sera15
0
130
システム思考で問題に対処する
yussak
0
210
Goでデータパイプラインを作ろう
sansantech
PRO
1
360
『三匹の子ぶた』から学ぶネットワークセキュリティの昔と今 / Network Security: Then and Now Through the Lens of The Three Little Pigs
nttcom
1
1.8k
修正PRを食べてレビュースキルが賢くなる:Claude Codeによる自己改善サイクル
yuyaumetsu
6
1.4k
Featured
See All Featured
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
400
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
2.3k
Paper Plane (Part 1)
katiecoart
PRO
1
10k
Typedesign – Prime Four
hannesfritz
42
3.1k
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
280
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
570
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
480
Building Adaptive Systems
keathley
44
3.2k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
490
What's in a price? How to price your products and services
michaelherold
247
13k
A Soul's Torment
seathinner
6
3.4k
Raft: Consensus for Rubyists
vanstee
141
7.6k
Transcript
@tarendai https://tomjn.com Using Blocks Outside The Editor
@tarendai https://tomjn.com
@tarendai https://tomjn.com Frontenberg https://frontenberg.tomjn.com
@tarendai https://tomjn.com
@tarendai https://tomjn.com Frontenberg Is not a frontend editor!
@tarendai https://tomjn.com Blocks are the Interface
@tarendai https://tomjn.com
@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)"); }, } );
@tarendai https://tomjn.com
@tarendai https://tomjn.com
@tarendai https://tomjn.com Building a Block Editor Component
@tarendai https://tomjn.com function Editor({ startingContent, inputName }) { return <div
className="editor-styles-wrapper"> .... </div>; }
@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>; }
@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>; }
@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>; }
@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>; }
@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>; }
@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>; }
@tarendai https://tomjn.com
@tarendai https://tomjn.com Building a Generic JS Function
@tarendai https://tomjn.com tomjn_wp_editor( 'The ID of the tag', 'The desired
input name', 'Starting content' );
@tarendai https://tomjn.com
@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 ); }
@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); ... }
@tarendai https://tomjn.com ... ReactDOM.render( <Editor startingContent={content} inputName={inputName} />, element );
}
@tarendai https://tomjn.com Commenting
@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 ); } });
@tarendai https://tomjn.com Building a Generic PHP function
@tarendai https://tomjn.com
@tarendai https://tomjn.com <?php wp_editor( $content, $editor_id, [] ); ?>
@tarendai https://tomjn.com <?php wp_block_editor($content, $name); ?>
@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 }
@tarendai https://tomjn.com Supporting PHP Code
@tarendai https://tomjn.com 1. setup the core data layer 2. enqueue
styles and scripts
@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 );', '} )();', ]) );
@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');
@tarendai https://tomjn.com I'm Tom J Nowell @tarendai https://tomjn.com WordPress VIP
@tarendai https://tomjn.com https://wpvip.com/careers
@tarendai https://tomjn.com
@tarendai https://tomjn.com