Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Block Editor カスタマイズ入門 #WPmeetupOsaka / Get star...

Block Editor カスタマイズ入門 #WPmeetupOsaka / Get started customize for block editor

Kansai WordPress Meetup Osaka の登壇資料です。
サンプルコード:https://github.com/torounit/my-first-block

Toro_Unit (Hiroshi Urabe)

November 16, 2019
Tweet

More Decks by Toro_Unit (Hiroshi Urabe)

Other Decks in Technology

Transcript

  1. Toro_Unit ઎෦ ߛ (͏Β΂ ͻΖ͠) • Frontend Developer • WordPress

    Plugin and Theme Developer Github: @torounit Twitter: @Toro_Unit 5
  2. 6

  3. Plugins and Themes • Custom Post Type Permalinks • Advanced

    Posts Blocks • Simple Post Type Permalinks • Powerful Posts Per Page (PPPP) • Vanilla • and more... 7
  4. 8

  5. 10

  6. WordPress ͱ͍͏ CMS ͷ HTML؅ཧ • post_content ͷΧϥϜʹ HTML ΛอଘɻͦΕΛग़ྗ͢Δ૷ஔɻ

    • HTML Λԣஅతʹ؅ཧ͢Δ࢓૊ΈͰ͋Γɺ୯Ұͷϖʔδͦͷ΋ͷΛ؅ཧ͢Δ ࢓૊ΈͰ͸ͳ͍ɻਤॻؗɻ • σʔλΛݩʹ HTML Λੜ੒͢ΔΘ͚Ͱ͸ͳ͍ɻ΄΅׬੒඼ͷ HTML ʹςʔ Ϛͱ͍͏෰Λணͤͯ഑৴͢Δ૷ஔɻ • ͍ͬͯ͏͔࠷ॳ (0.71)͸ɺςʔϚ͢Βແ͔ͬͨɻ • https://github.com/mt8/wbkobe77/blob/master/index.php 18
  7. 19

  8. ͱΓ͋͑ͣɺeditor-styles ͸ඞͣઃఆ͢ΔΑ͏ʹ͠·͠ΐ͏ɻ <?php function my_theme_setup() { add_theme_support('editor-styles'); add_editor_style( 'style-editor.css' );

    } add_action( 'after_setup_theme'); ϨΠΞ΢τ΍σβΠϯͷࣗ༝౓্͕͕ͬͯ΋ɺαΠτͷදࣔͱΤσΟλ ͷݟͨ໨͕Ұக͍ͯ͠ͳ͍ͱ͋Μ·Γҙຯͳ͍ɻ 28
  9. editor-style ΛΘ͟Θ͟࡞ΔͷΊΜͲ͘͞ ͍ͬͯਓ͸ɺ ࢖͍΍͍͢WordPressͷͨΊ ͷCSSͷͭ͘Γ͔ͨ ͬͯ࿩Λɺ2015೥ͷ WordBench Osaka Ͱ΍ͬͯΔͷͰͦΕಡΜ ͰԼ͍͞ɻ

    https://www.slideshare.net/Toro_Unit/ wordpresscss ݹ͍৘ใ΋͋Γ·͕͢ɺ͋Μ·Γߟ͑ํม Θͬͯ·ͤΜɻ๻͸ SMACSS + BEM ͬͯײ ͡Ͱ CSSॻ͍ͯ·͢ɻ 29
  10. 33

  11. ϒϩοΫελΠϧ GUI ͰɺϒϩοΫʹΫϥεΛઃఆग़དྷΔɻ͍ͭͰʹϓϨϏϡʔ΋͍ͭͯ ͘Δɻඇৗʹศརɻ ઃఆ͞ΕΔ஋͸ɺis-style-hoge ͷΑ͏ͳܗࣜɻ "ߴ౓ͳઃఆ" ύωϧ಺ͷ "௥ՃCSS Ϋϥε"

    Λૢ࡞͍ͯ͠Δ͚ͩɻ Documentation : https://developer.wordpress.org/block-editor/ developers/filters/block-filters/#block-style-variations 34
  12. ࣮૷ํ๏ɻ ΤσΟλʔʹಡ·ͤΔ js ͷઃఆɻwp-blocks Λґଘؔ܎ʹࢦఆ <?php function my_block_editor_assets() { wp_enqueue_script(

    'my-block-editor-style', 'path/to/my-block-editor-style.js', array( 'wp-blocks' ) ); } add_action( 'enqueue_block_editor_assets', 'my_block_editor_assets' ); 35
  13. ֓ཁ • wp_register_script Ͱ js ϑΝΠϧΛಡΈࠐΉɻͦͷ͋ͱ͸ɺJSͰ ʢͱ͍͏ΑΓɺReact ͰʣΰϦΰϦ͢Δɻ • PHPͰͷϨϯμϦϯάΛهड़͢Δ͜ͱͰಈతͳཁૉ

    (γϣʔτίʔ υɺ΢ΟδΣοτͷΑ͏ͳ) Λఏڙग़དྷΔɻ • ex. WP_Query Ͱ౤ߘͷ৘ใΛදࣔɻ • JSʢ React ʣ ͸ඞͣ࢖͏ɺPHP ͸ͨ·ʹ࢖͏ఔ౓ɻ 39
  14. React Ή͔͍ͭ͠ ? • React ΋ษڧ͠Α͏ɻ͋Μͳͷ HTML Έ͍ͨͳ΋ͷͩʢચ೴ • ΧελϜϒϩοΫ։ൃͳΒɺHTML

    ʹໟ͕ੜ͑ͨҐͰ৐Γ੾ΕΔέʔε ΋݁ߏ͋Δɻ • ͪΐͬͱͨ͠ϞϊΛ࡞Δͷ͸͞΄Ͳ೉͘͠ͳ͍ɻߴػೳͳϞϊͭ͘Ζ͏ͱ ͢Δͱ೉͍͠ɻ • ͱ͍͏͔ɺঢ়ଶ؅ཧ / ඇಉظ / ௨৴ / GUIͰΰϦΰϦ΍Δͷ͕ͦ΋ͦ΋೉ ͍͠ɻͦͷ೉͠͞Λղܾ͢ΔϞϊͷ͕̍ͭ React. 41
  15. import { registerBlockType } from '@wordpress/blocks'; import { InnerBlocks }

    from '@wordpress/block-editor'; const edit = ( { className } ) => ( <section className={ className }> <div className="wp-block-my-block-section__container"> <InnerBlocks /> </div> </section> ); const save = ( { className } ) => ( <section className={ className }> <div className="wp-block-my-block-section__container"> <InnerBlocks.Content /> </div> </section> ); 44
  16. registerBlockType( 'my-block/section', { title: 'section', description: 'section', icon: 'text-page', category:

    'layout', supports: { align: [ 'wide', 'full' ], anchor: true, }, edit, save, } ); 45
  17. ४උɻ ͱΓ͋͑ͣద౰ʹ WordPress ͷϓϥάΠϯΛ࡞੒͠·͢ɻ ϑΝΠϧߏ੒ - my-first-block - package.json -

    my-first-block.php ( js ͷొ࿥ͱ͔ɺWordPressϓϥάΠϯຊମ ) - src/index.js ( ͜͜ʹΰϦΰϦ͢Δɻ) 49
  18. package.json { "name": "my-first-block", "version": "0.0.1", "license": "GPL2.0+", "devDependencies": {

    "@wordpress/scripts": "^5.0.0" }, "scripts": { "start": "wp-scripts start", "build": "wp-scripts build", } } ͜Ε͚ͩͰ OK 50
  19. @wordpress/scripts https://www.npmjs.com/package/@wordpress/scripts • JSͷࣗಈϏϧυͱ͔ɺBabel ͱ͔ɺWebpack ͱ͔ɺESLint ͱ͔ɺ WordPressϓϥάΠϯ։ൃ؀ڥͷߏஙʢཁ docker-compose ʣͱ͔

    ͳΜͰ΋΍ͬͯ͘ΕΔ͍͢͝Ϡπɻ • PostCSS / SCSS ͷϏϧυ͸ࠓͷͱ͜Ζग़དྷͳ͍͚Ͳɺ௥Ճ͞ΕΔ͔ ΋ɻhttps://github.com/WordPress/gutenberg/issues/14801 51
  20. • @wordpress/blocks -> wp.blocks ͷΑ͏ʹɺάϩʔόϧม਺Λࢀ র͢ΔΑ͏ʹม׵ͯ͘͠ΕΔɻ import { registerBlockStyle }

    from '@wprdpress/blocks' Λɺ const { registerBlockStyle } = wp.blocks; Έ͍ͨʹͯ͘͠ΕΔɻ • jQuery ౳ͷ WordPress ʹಉࠝ͞Ε͍ͯΔJS΋ಉ༷ɻ • ςʔϚ։ൃͳͲͰ΋ศརʹ࢖͑Δɻ 53
  21. my-first-block.php function my_first_block_register_block() { $asset_file = include( plugin_dir_path( __FILE__ )

    . 'build/index.asset.php'); wp_register_script( 'my-first-block', plugins_url( 'build/index.js', __FILE__ ), $asset_file['dependencies'], $asset_file['version'] ); // block ͷొ࿥ɻ register_block_type( 'my-first-block/hello', array( 'editor_script' => 'my-first-block', ) ); } add_action( 'init', 'my_first_block_register_block' ); 54
  22. build/index.asset.php wp_register_script ͢Δͱ͖ͷɺґଘؔ܎ɺversion ౳ΛɺJS ͔Βࣗಈతʹ൑ผͯ͠࡞੒͞Ε Δɻࠓ·ͰखಈͰ΍ͬͯͨͷ͕ΞϗΈ͍ͨʹࢥ͑Δ͘Β͍ศརɻ <?php return array( 'dependencies'

    => array( 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose','wp-data', 'wp-element', 'wp-i18n', 'wp-polyfill' ), 'version' => '3ba4a1cc34f9a198d6519b52f8622629' ); 55
  23. register_block_type ϒϩοΫͷొ࿥Λߦ͏ɻࣄલʹ JS౳ͷొ࿥͕ඞཁͳͷͰɺwp_register_script Ͱ֤ࣗ΍ͬͯ ͍ͩ͘͞ɻ <?php register_block_type( 'ϒϩοΫϥΠϒϥϦɾϓϥάΠϯ໊/ϒϩοΫ໊', array( 'script'

    => 'ొ࿥ͯ͋͠Δjsͷ໊લɺϑϩϯτ/؅ཧը໘༻', 'style' => 'ొ࿥ͯ͋͠ΔCSSͷ໊લɺϑϩϯτ/؅ཧը໘༻', 'editor_script' => 'ొ࿥ͯ͋͠Δjsͷ໊લɺ؅ཧը໘༻', 'editor_style' => 'ొ࿥ͯ͋͠ΔCSSͷ໊લɺ؅ཧը໘༻', ) ); editor_script ͚ͩ͋Ε͹OK. ϓϥάΠϯଆͰ༻ҙͨ͠CSSͱ͔Λಡ·ͤͨΓ΋Ͱ͖Δɻ 56
  24. import { registerBlockType } from '@wordpress/blocks'; // const { registerBlockType

    } = wp.blocks ʹม׵͞ΕΔ registerBlockType( 'my-first-block/hello', { title: 'hello', icon: 'palmtree', // Dashicons. ௚઀ <svg></svg>ͷࢦఆ΋ग़དྷΔ category: 'common', // ΠϯαʔλʔͷͲͷύωϧʹදࣔ͢Δ͔ɻ edit({ className } ) { return ( <div className={ className }>ΤσΟλʔͩΑɻ</div> ); }, save({ className } ) { return ( <div className={ className }>อଘ͞ΕΔσʔλɺ࣮ࡍʹදࣔ͞ΕΔςΩετɻ</div> ); }, } ); 59
  25. 60

  26. import { registerBlockType } from '@wordpress/blocks'; import { RichText }

    from '@wordpress/block-editor'; const edit = ( { className, attributes: { text }, setAttributes } ) => { const onChange = ( value ) => { return setAttributes( { text: value } ); }; return ( <div className={ className }> <TextControl value={ text } onChange={ onChange } /> </div> ); }; const save = ( { className, attributes: { text } } ) => { return ( <div className={ className }> <div className="text">{ text }</div> </div> ); }; 65
  27. import { registerBlockType } from '@wordpress/blocks'; import { TextControl }

    from '@wordpress/components'; const edit = ( { className, attributes: { text }, setAttributes } ) => { const onChange = ( value ) => { return setAttributes( { text: value } ); }; return ( <div className={ className }> <TextControl value={ text } onChange={ onChange } /> </div> ); }; const save = ( { className, attributes: { text } } ) => { return ( <div className={ className }> <div className="text">{ text }</div> </div> ); }; 68
  28. const edit = ( { className, attributes: { text },

    setAttributes } ) => { const onChange = ( value ) => { return setAttributes( { text: value } ); }; return ( <div className={ className }> <TextControl value={ text } onChange={ onChange } /> </div> ); }; 69
  29. <TextControl /> • @wordpress/components ఏڙ͞ΕΔίϯϙʔωϯτɻinput λάΛ ు͖ग़͢ɻϑΥʔϜͷ෦඼ͳͲ͸ɺ΄΅શͯ༻ҙ͞Ε͍ͯΔɻ • ex. <SelectControl

    />, <DateTime /> @wordpress/components ʹ͸ଞʹ΋༷ʑͳίϯϙʔωϯτ͕͋Δɻ Component Reference: https://developer.wordpress.org/block- editor/components/ 70
  30. attributes ϓϩύςΟ registerBlockType( 'my-first-block/hello', { title: 'hello', icon: 'palmtree', category:

    'common', attributes: { text: { type: 'string', default: '', }, }, edit, save, } ); อଘ͢ΔσʔλͷܗࣜΛఆٛɻσʔλܕɺσϑΥϧτ஋ͳͲɻ഑ྻͳͲ΋ࢦఆՄೳɻ 71
  31. attirubutes, setAttirubutes const edit = ( { className, attributes: {

    text }, setAttributes } ) => { const onChange = ( value ) => { return setAttributes( { text: value } ); }; return ( <div className={ className }> <TextControl value={ text } onChange={ onChange } /> </div> ); }; TextControl ͷத਎͕มߋ͞ΕͨΒɺݱࡏͷ attributes Λ࠶ઃఆɻߋ৽͢Δ஋ͷΈ Λهड़ɻ https://developer.wordpress.org/block-editor/developers/block-api/block- attributes/ 72
  32. <!-- wp:my-first-block/hello {"text":"Hello!!!"} --> <div class="wp-block-my-first-block-hello"><div class="text">Hello!!!</div></div> <!-- /wp:my-first-block/hello -->

    attirbutes ͸ɺίϝϯτͱͯ͠อଘ͞Ε͍ͯΔɻ( the_cotent Ͱు͖ग़ ͢ࡍʹ͸ɺϑΟϧλʔͰ࡟আ͞ΕΔ) 74
  33. <RichText /> ฤूग़དྷΔςΩετΛఏڙ͢ΔίϯϙʔωϯτɻίΞͷϒϩοΫ΋ςΩετฤू ग़དྷΔ΋ͷ͸͍͍ͩͨ͜ΕͰग़དྷͯΔɻվߦͱ͔΋औΓѻ͑Δɻ • <RichText /> : ΤσΟλը໘༻ɻ •

    <RichText.Content /> : HTMLΛు͖ग़͢༻ɻ <RichText.Content tagName='p' value='Hello' /> <p>hello</p> https://developer.wordpress.org/block-editor/developers/richtext/ 76
  34. import { registerBlockType } from '@wordpress/blocks'; import { RichText }

    from '@wordpress/block-editor'; const edit = ( { className, attributes: { text }, setAttributes } ) => { const onChange = ( value ) => setAttributes( { text: value } ); return ( <div className={ className }> <RichText tagName="div" className="text" value={ text } onChange={ onChange } /> </div> ); }; const save = ( { className, attributes: { text } } ) => { return ( <div className={ className }> <RichText.Content tagName="div" className="text" value={ text } /> </div> ); }; 77
  35. 78

  36. source ʹࢦఆͰ͖Δ஋ • html: innerHTML Λऔಘɻෳ਺ߦͰ΋औಘͯ͠഑ྻʹग़དྷͨΓ͢ Δɻ • text: textContent

    Λऔಘ • attribute : ଐੑ஋Λऔಘ • query: ෳ਺ͷଐੑ΍ɺςΩετͳͲΛऔಘͯ͠ΦϒδΣΫτʹɻ 86
  37. υΩϡϝϯςʔγϣϯʹॻ͍ͯແ͍΋ͷ • children : ࢠཁૉɻ • node / tag :

    ࢖͍Ͳ͜Ζ͕ྑ͘ղΒͳ͍ • property: ιʔείʔυʹ͚͋ͬͨͲͳΜ͔ͩղΒͳ͍ɻ 87
  38. Note: ΧελϜϑΟʔϧυͱͷ࿈ܞ΋ग़དྷΔɻ register_post_meta( 'post', 'my_post_sub_title', array( 'show_in_rest' => true, 'single'

    => true, 'type' => 'string', ) ); attributes: { author: { type: 'string', source: 'meta', meta: 'my_post_sub_title' }, }, ΧελϜϑΟʔϧυͷΩʔΛ post_hoge ͱ͔ʹ͢Δͱಈ͔ͳ͍ͷͰ஫ҙɻ 88
  39. const edit = ( props ) => { // ஋ͷ४උͱ͔͍Ζ͍Ζ΍Δɻ

    return ( <div> <InspectorControls> <PanelBody> // ઃఆͱ͔ </PanelBody> </InspectorControls> <BlockControls> <Toolbar controls={ controls } /> </BlockControls> <div> //ϒϩοΫຊମ </div> </div> ) }; 90
  40. InnerBlocks ϒϩοΫͷதʹϒϩοΫΛೖΕΒΕΔϠπɻΧϥϜϒϩοΫɺάϧʔϓϒϩοΫɺJetpack ͷίϯλΫτ ϑΥʔϜ౳Ͱ༻͍ΒΕ͍ͯΔɻallowedBlocks Λࢦఆ͢ΔͱɺதʹೖΕΒΕΔϒϩοΫΛ੍ݶͰ͖Δɻ const edit = ( {

    className } ) => ( <div className={ className }> <InnerBlocks allowedBlocks={ [ 'core/code' ] } /> </div> ); const save = ( { className } ) => ( <div className={ className }> <InnerBlocks.Content /> </div> ); 91
  41. 94

  42. ࡞Γํ render_callback ͱɺඞཁͰ͋Ε͹ɺattributes Λࢦఆɻ௨ৗͷϒϩοΫͱҧ͍ɺattributes Ͱࢦఆ͠ͳ͍ͱɺclassName ΛҾͬுͬͯདྷΕͳ͍ɻ register_block_type( 'my-first-block/hello', array( 'editor_script'

    => 'my-first-block', 'attributes' => [ 'className' => [ 'type' => 'string', 'default' => '', ], ], 'render_callback' => 'my_first_block_render' ) ); 95
  43. example.1 ୈ2Ҿ਺ʹ͸ɺsave ͞ΕͨHTML͕ͦͷ··౉͞ΕΔͷͰɺ͜ΕΛPHPଆͰɺද੍ࣔ ޚɻ function my_first_block_render( $attributes, $content ) {

    if ( get_current_user_id() ) { return $content; } return sprintf( '<div class="%1$s">login to see this content.</div>', $attributes['className'] ); } 96
  44. JSଆ͸ී௨ʹॻ͘ɻ const edit = ( { className } ) =>

    ( <div className={ className }> <InnerBlocks /> </div> ); const save = ( { className } ) => ( <div className={ className }> <InnerBlocks.Content /> </div> ); 97
  45. example.2 function my_first_block_render( $attributes, $content ) { if ( get_current_user_id()

    ) { return sprintf( '<div class="%1$s">Hello %2$s !!</div>', $attributes['className'], wp_get_current_user()->display_name ); } } 100
  46. import { registerBlockType } from '@wordpress/blocks'; import { useSelect }

    from '@wordpress/data'; // JS ͰίΞͷσʔλΛҾͬுͬͯ͘Δɻ export const useCurrentUser = () => { return useSelect( ( select ) => { return select( 'core' ).getCurrentUser(); } ); }; const edit = ( { className } ) => { const { name } = useCurrentUser(); return ( <div className={ className }> Hello { name } !! </div> ); }; // શͯ PHP ͰϨϯμϦϯά͢Δ৔߹͸ɺsave ͸ null. const save = () => null; 101
  47. Note: ΤσΟλ্Ͱ΋αʔόʔαΠυϨϯμϦϯάग़དྷΔ import { ServerSideRender } from '@wordpress/components'; const edit

    = ( { className } ) => ( <ServerSideRender block="my-first-block/hello" attributes={ { className, } } /> ); 103
  48. ·ͣɺReact ͱ஥ྑ͘ͳΔɻ • ͱΓ͋͑ͣɺcreate-react-app ౳Ͱ؆ ୯ͳΞϓϦΛ࡞ͬͨΓ͢Δͷେࣄɻ • WordPress Meetup Map

    ΋ͦͷҰ؀ɻ • ͍ͭͰʹ Redux ͱ͔΋৮͓ͬͯ͘ͱ͍ ͍ɻʢ಺෦తʹ࢖ΘΕ·ͬͯ͘Δɻʣ 107
  49. ਓͷϓϥάΠϯΛಡΉɻ • LIQUID BLOCKS: https://wordpress.org/plugins/liquid-blocks/ • Snow Monkey Blocks: https://wordpress.org/plugins/snow-monkey-blocks/

    • Slide: https://github.com/WordPress/slides • ࠓ೥ͷ WordCamp US Ͱͷ matt ͰͷηογϣϯͷεϥΠυ͸͜ΕͰ࡞ΒΕ ͍ͯΔɻ* ίΞίϛολʔͰΤσΟλʔνʔϜͷɺElla ͞Μ࡞ɻͺͶ͐ɻ 110
  50. 118