記事の方もReact使って書けないかと考えてみる。
エディタがGutenbergになってReact使えるようになったけど、記事の中身にReactを使えるわけではないみたい。せっかくBlockのエディタ側で使えるのだから、そのままブログ記事の方でReactを使えないか実験。
ゴール
今回は出来上がったら、記事のなかにReactのコンポーネント「gromment アナログ時計」をこんな感じで表示できるBlockが使えるようになります。

準備
ベースにするBlockを作成
Block ジェネレータに、これ「create-guten-block」を使っています。
pluginsフォルダに移動
ターミナルを開いて、自分のwordpressのpluginsフォルダで実行します。私の場合、こんな感じのフォルダ。
cd /var/www/html/wp-content/plugins
Blockを作成
移動したら、「create-guten-block」コマンドで、pluginのテンプレートをジェネレート
npx create-guten-block my-block
cd my-block
ここまで行ったら、次のコマンドを打って、自動ビルドをSTARTします。
npm start
ファイル構成
ベースのBlockを作ったあと、記事用のjavascriptファイルをビルドするためのフォルダを front という名前で作成します。

このフォルダの中身は、エディタ用のBlockとは別にwebpackでビルドします。(※ 前回の記事「Webpackでnode_modulesを一つのファイルにする」でwebpackの使い方を書いています)

Frontを実装
中身はこんな感じで実装します。
index.js
最後の方の、ReactDOM.renderで、’clock’ を指定しています。このjavascriptファイルを使うためには、 <div id=”clock”></div> のような感じで id に’clock’ を指定した html が必要になります。これは、あとでBlockのEditorの方で作ります。
import React from "react";
import ReactDOM from "react-dom";
import { Box, Grommet, Clock } from "grommet";
import { grommet } from "grommet/themes";
const AnalogClock = () => (
<Grommet theme={grommet}>
<Box align="center" justify="start" pad="large">
<Clock type="analog" />
</Box>
</Grommet>
);
ReactDOM.render(
<AnalogClock />,
document.getElementById('clock')
);
package.json
{
"name": "front",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"grommet": "^2.2.1",
"react": "^16.7.0",
"react-dom": "^16.7.0",
"styled-components": "^4.1.3"
},
"devDependencies": {
"@babel/core": "^7.2.2",
"@babel/preset-env": "^7.2.3",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.5",
"webpack": "^4.28.3",
"webpack-cli": "^3.2.1"
}
}
webpack.config.js
module.exports = {
entry: __dirname + "/index.js",
output: {
path: __dirname + "/dist",
filename: "bundle.js"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['@babel/preset-env','@babel/preset-react']
}
}
]
},
}
Frontをビルド
frontフォルダの package.jsonのあるフォルダに移動して、こんな感じで、npm、webpackと順番にコマンドを打っていきます。distフォルダと、その下にbundle.jsonというファイルが出来上がれば、OKです。
npm install
npx webpack
Editorを実装
editor側はこの二つのファイルを実装していきます。エディタ側のinit.phpで「wp_enqueue_script」を使って上のFrontでビルドしたbundle.jsをブログ記事で読み込むようにしています。
- my-block/src/block.js
- my-block/src/init.php

block.js
ここは、frontのbundle.jsにある ‘clock’ をidに持ったDivを save: に、edit: の方は、ただ文字「Analog Clock」と表示するようにします。
/**
* BLOCK: my-block
*
* Registering a basic block with Gutenberg.
* Simple block, renders and saves the same content without any interactivity.
*/
// Import CSS.
import './style.scss';
import './editor.scss';
const { __ } = wp.i18n; // Import __() from wp.i18n
const { registerBlockType } = wp.blocks; // Import registerBlockType() from wp.blocks
registerBlockType( 'cgb/block-my-block', {
// Block name. Block names must be string that contains a namespace prefix. Example: my-plugin/my-custom-block.
title: __( 'my-block - CGB Block' ), // Block title.
icon: 'shield', // Block icon from Dashicons → https://developer.wordpress.org/resource/dashicons/.
category: 'common', // Block category — Group blocks together based on common traits E.g. common, formatting, layout widgets, embed.
keywords: [
__( 'my-block — CGB Block' ),
__( 'CGB Example' ),
__( 'create-guten-block' ),
],
edit: function( props ) {
// Creates a <p class='wp-block-cgb-block-my-block'></p>.
return (
<div className={ props.className }>
<p>Analog Clock</p>
</div>
);
},
save: function( props ) {
return (
<div id="clock"/>
);
},
} );
init.php
wp_enqueue_scriptの引数は、一番最後のscriptをfooterにというところをちゃんとtrueで指定しておかないと、<div id=’clock’> が読み込まれる前に、jsが実行されてしまい、react minified error が出るので注意。
<?php
/**
* Blocks Initializer
*
* Enqueue CSS/JS of all the blocks.
*
* @since 1.0.0
* @package CGB
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
function my_block_cgb_block_assets() { // phpcs:ignore
wp_enqueue_script(
'my_block-cgb-block-js', // Handle.
plugins_url( '/front/dist/bundle.js', dirname( __FILE__ ) ),
'',
'',
true// Enqueue the script in the footer.
);
}
// Hook: Frontend assets.
add_action( 'enqueue_block_assets', 'my_block_cgb_block_assets' );
function my_block_cgb_editor_assets() { // phpcs:ignore
wp_enqueue_script(
'my_block-cgb-block-js', // Handle.
plugins_url( '/dist/blocks.build.js', dirname( __FILE__ ) ), // Block.build.js: We register the block here. Built with Webpack.
array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-editor' ), // Dependencies, defined above.
'',
true // Enqueue the script in the footer.
);
}
// Hook: Editor assets.
add_action( 'enqueue_block_editor_assets', 'my_block_cgb_editor_assets' );
Blockを確認
wordpressの設定画面で、pluginをactivateしたあと、記事の投稿でBlockが使えるようになっていれば完成です。(※ Plugin名、Block名は、ジェネレーターで作成されたものをそのまま使っていれば、my-block と言う名前になっていると思います。)
投稿画面
