[WordPress] Gutenbergことはじめ

本記事は、[WordPress Advent Calendar 2017](https://qiita.com/advent-calendar/2017/wordpress)の7日目です。

## Gutenbergとは

Gutenbergとは、WordPressのエディタ画面の新UXのことです。UIではなくUXというところがミソで、記事を編集する際の体験はGutenbergで大きく変わることが期待されます。一方で、今まで蓄積されてきたWordPressのエディタのカスタマイズ方法が使えなくなるという、大きな変化も伴っています。

本記事では、はじめにGutenbergの開発環境をローカルに構築し、手元で動かしてみます。次に、GutenbergのキモであるBlock（ブロック）について解説します。

## 開発環境セットアップ

Gutenbergは、[WordPressプラグイン](https://wordpress.org/plugins/gutenberg/)として公開されています。手元に適当なWordPress環境があれば、それにこのプラグインを入れればお手軽にGutenbergを試すことができます。

本記事では、Gutenbergのソースコードを見たり、改造したりしてみたりしたい人のため、Gutenbergプロジェクトが公式に用意している開発環境セットアップ方法を解説します。

### 必要なソフトウェア

以下のソフトウェアが必要です。Dockerは最新版、Node.jsは6.x以上が推奨です。

- Docker
- Node.js

セットアップ用のシェルスクリプトを動かすにはbashが必要です。

### ダウンロードとセットアップ

まず、[GitHub](https://github.com/WordPress/gutenberg)からソースコードをダウンロードします。ダウンロードしたら、`./bin/setup-local-env.sh`を実行します。このシェルスクリプトはdocker-composeコマンドを呼び出してDocker環境を構築し、Docker環境にローカルディレクトリをマウントします。

うまくいけば、 http://localhost:8888/ でWordPressが動いているはずです。wp-adminには、ユーザ名：`admin`、パスワード：`password`でログインできます。また、Gutenbergが自動的に有効化されています。

<img width="801" alt="Screen Shot 2017-12-06 at 23.34.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/33450/6c719d57-07a6-7cd0-7c68-3cbfbf814e01.png">

次回以降は、`docker`ディレクトリ内で`docker-compose up -d`すれば開発環境を起動できます。

## ブロックとは

Gutenbergでは、「ブロック(Block)」が中心的な概念となっています。ブロックは、一般的なJavaScriptフレームワーク(React.js等)で言うところの「コンポーネント」に近い概念ですが、ブログ記事の編集という用途に特化しています。

Gutenbergには多数のブロックが組み込まれています。

<img width="307" alt="Screen Shot 2017-12-06 at 23.35.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/33450/dea24eff-6f0c-5fc5-5803-2d6fbbd5a61b.png">

Gutenbergを使った編集の流れは、(1) ブロックの選択 (2) ブロックにコンテンツを入れる (3) 保存して公開する となります。

現在のWordPressでは、出力するコンテンツをカスタマイズする方法が様々にあります。Gutenbergのブロックは、これら**全て**の置き換えを意図した機能です。以下は[Introducing a new way to WordPress](https://wordpress.org/gutenberg/)というGutenbergの紹介記事からの引用です。

> The Gutenberg editor uses blocks to create all types of content, replacing a half-dozen inconsistent ways of customizing WordPress, bringing it in line with modern coding standards, and aligning with open web initiatives.
*Gutenbergエディタはブロックを使ってあらゆる種類のコンテンツを作成する。（ブロックは）半ダースにも及ぶ、一貫性のないWordPressのカスタマイズ方法を置き換えるものであり、モダンなコーディング標準に準拠し、オープンWebの取り組みと協調するためのものである。*

> These blocks are a unified way to style content that currently requires shortcodes, embeds, widgets, post formats, custom post types, theme options, meta-boxes, and other formatting elements. 
*Gutenbergのブロックは、コンテンツの見た目を整えるための統合された方法である。（現在のWordPressでは、見た目を整えるのにショートコード等様々な手段を用いる必要がある。）*

### ブロックの仕組み

WordPressの記事は、wp_postsテーブルのpost_contentというカラムに保存されます。この仕組みはGutenbergでも変わりません。しかし、Gutenbergでは、post_contentに保存するコンテンツの中に、本文以外のメタ情報がHTMLコメントという形で含まれます。

はじめに、以下のような記事を作成します。

- タイトル: Gutenberg: The Basics
- 見出し: What is Gutenberg?
- カバー画像1枚
- 段落: Gutenberg is a new UX of WordPress editor.

<img width="626" alt="Screen Shot 2017-12-07 at 0.11.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/33450/b3a03ea9-a1f4-897d-f5c5-9cdd5b3562b8.png">

これを保存して、post_contentの中を見てみます。

```html
<!-- 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 -->
```

`<!-- 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} -->` が、ブロックのメタデータです。メタデータは、HTMLコメントの中にJSON形式で埋め込まれます。また、これらは描画後のHTMLからは消え去り、最終的には以下のようなHTMLが得られます。

```html
<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>
```

ここで、**描画**という言葉を使いました。Gutenbergは、post_contentに含まれるHTMLコメントを解釈して、ふさわしい形で描画を行います。

では、Gutenbergを使って編集したコンテンツは、Gutenbergなしでは表示できなくなってしまうのでしょうか？　先ほどのpost_contentを思い出してください。HTMLコメントはあくまでメタデータ置き場で、コンテンツ自体はすでにHTMLとして保存されていました。このように、Gutenbergはコンテンツの互換性にも配慮がされています。

では、次にもう少し高度なブロックとして、Twitterのウィジェットを見てみましょう。Embedsのリストの中からTwitterを選んで、埋め込みたいツイートのURLを設定すると、以下のように埋め込みされます。

<img width="539" alt="Screen Shot 2017-12-07 at 0.38.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/33450/7b2118aa-83ef-1ca5-513f-7159dea9d6bb.png">

post_contentは以下のようになっています。

```html
<!-- wp:core-embed/twitter {"url":"https://twitter.com/ryo511/status/938424719610544129"} -->
<figure class="wp-block-embed-twitter">
    https://twitter.com/ryo511/status/938424719610544129
</figure>
<!-- /wp:core-embed/twitter -->
```

これはサーバサイドで以下のように描画されます。この時点でTwitterの本文とリンクは描画されています。

```html
<figure class="wp-block-embed-twitter">
<blockquote class="twitter-tweet" data-width="525" data-dnt="true">
<p lang="ja" dir="ltr">New post: Gutenberg Handbook 読書メモ <a href="https://t.co/cmscP95iF8">https://t.co/cmscP95iF8</a></p>
<p>— Ryo (@ryo511) <a href="https://twitter.com/ryo511/status/938424719610544129?ref_src=twsrc%5Etfw">December 6, 2017</a></p></blockquote>
<p><script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script><br>
</p></figure>
```

注目すべきは `<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>` で、TwitterのウィジェットのJavaScriptを呼ぶことで、動的な描画を行っています。最終的な描画結果のHTMLは150行ほどになります。

## What's next

ここまで、Gutenbergの概要、開発環境の構築と、ブロックの基本的な仕組みを解説しました。

この先、独自ブロックの作成方法等を学ぶには、[Gutenberg Handbook](https://wordpress.org/gutenberg/handbook/)を読むのが良いでしょう。また、本Advent Calendarでも独自ブロックの作成方法について解説する予定です。