Gutenberg
解体新書(初稿)
Ryo Utsunomiya(@ryo511)
WordCamp Tokyo 2018
2018-09-15
Gutenbergはどういう技術で成り立っているのか
GutenbergはWordPressプラグイン
主要成分はJavaScript
Webブラウザ上で動作するプログラミング言語
ECMAScriptの仕様化には、ブラウザでの実装状況も考慮される
Gutenbergでは、JavaScriptのライブラリ管理にはnpm(Node Package Manager)を使用している
dependencies(動作に必要なライブラリ)と、devDependencies(開発に必要なライブラリ)に分かれる
Gutenbergの中心を成すライブラリ
React.jsは、リッチな=複雑なUIを、効率よく開発するためのライブラリ
// ES2015のclass構文
class HelloMessage extends React.Component {
render() {
return (
// JavaScriptの中にHTMLを書く(JSX)
<div>
Hello {this.props.name}
</div>
);
}
}
// #app というidを持つ要素にReactアプリケーションを描画
ReactDOM.render(
<HelloMessage name="Taylor" />,
document.getElementById("app")
);
最大の特徴は、JavaScriptの中にHTMLを書くこと
// JavaScript関数の戻り値にHTMLを書く
function Hello() {
return <div>Hello World</div>
}
// HTMLの中にJavaScriptの変数を埋め込むことができる
function Hello(name) {
return <div>Hello {name}</div>
}
// 関数呼び出しも可能
function Hello(name) {
return <div>{greeting(name)}</div>
}
React.jsは、JSXによって、高い表現力を実現している
JavaScriptトランスパイラ
// ESNext + JSX
const hw = <h1>Hello World</h1>;
// ES5(React)
var hw = React.createElement("h1", null, "Hello World");
// ES5(Gutenberg)
var hw = wp.element.createElement("h1", null, "Hello World");
// JSX
<div className="container">
<h1>Header1</h1>
<p>Paragraph</p>
</div>
// ES5
var el = wp.element.createElement;
el(
'div',
{ className: 'container' },
[
el( 'h1', null, 'Header1' ),
el( 'p', null, 'Paragraph' ),
],
);
webpackは、ES2015のモジュールシステムを、レガシーブラウザ(IE11等)でも動くようにするためのツール
jsファイルの外側から、ライブラリ等を読み込んで使用できるようにするための構文
GutenbergはWordPressプラグインとして実装され、
webpack + Babelのビルドの仕組み作りはそれなりに複雑で、学習コストがかかる
記事の編集に使用する、再利用可能な部品
自分で定義したブロックを登録し、Gutenberg で利用可能にできる
import HelloBlock from './HelloBlock';
wp.blocks.registerBlockType( 'my-block/hello', {
title: 'Greeting',
icon: 'cart',
category: 'common',
// ブロックがもつメタデータを定義
attributes: {
// 省略
},
// ブロックの初回表示・編集時の動作を定義
edit( { attributes, setAttributes } ) {
return (
<HelloBlock
attributes={ attributes }
setAttributes={ setAttributes }
/>
);
},
// ブロックを保存する際の動作を定義
save( { attributes } ) {
// 省略
},
} );
/* global React */
export default class HelloBlock extends React.Component {
render() {
const { name } = this.props.attributes;
return <div>{ name }</div>;
}
}
たとえば、コアの段落ブロックはParagraphBlockというReactコンポーネントとして実装されている
WordPressの記事データはwp_postsテーブルのpost_contentというカラムに保存される
<!-- wp:core/heading -->
<h2>What is Gutenberg?</h2>
<!-- /wp:core/heading -->
<!-- wp:core/cover-image {"url":"http://localhost:8888/wp-content/uploads/2017/12/Screen-Shot-2017-12-06-at-23.34.27.png","id":45} -->
<section class="wp-block-cover-image has-background-dim" style="background-image:url(http://localhost:8888/wp-content/uploads/2017/12/Screen-Shot-2017-12-06-at-23.34.27.png)">
</section>
<!-- /wp:core/cover-image -->
<!-- wp:core/paragraph -->
<p>Gutenberg is a new UX of WordPress editor.</p>
<!-- /wp:core/paragraph -->
Gutenbergブロックのメタデータは
HTMLコメントの中にJSON形式で埋め込まれる
<h2>What is Gutenberg?</h2>
<section class="wp-block-cover-image has-background-dim" style="background-image:url(http://localhost:8888/wp-content/uploads/2017/12/Screen-Shot-2017-12-06-at-23.34.27.png)">
</section>
<p>Gutenberg is a new UX of WordPress editor.</p>
edit() で初期状態を出力(保存されたコンテンツを編集する際は、以前の状態の復元)
通常のWordPressプラグインと変わらない
<?php
// index.php
/**
* Register Block JavaScript file.
*/
add_action( 'enqueue_block_editor_assets', function () {
wp_enqueue_script(
'my-block',
plugins_url( 'build/index.js', __FILE__ ),
array( 'wp-blocks', 'wp-element' )
);
} );
Gutenbergは様々なJavaScriptライブラリによって成り立っている
Gutenberg Handbook