「WordPressのカスタムブロックをペアプロで作ってみよう その2」ちゃんとペアプロしてみたよ

こんにちは、みみです。

本日(2021/12/08) WordPress 5.9 Beta 2 がリリースされました。そろそろ触ってみましょう。

が、そのちょっと前に、読む会ではこっそりYoutube配信第二弾をやっていました。ちゃんと配信できるか直前まで不明だったので配信始めてからのお知らせですみません。でも、アーカイブがあるのでよかったらご覧ください。

https://youtu.be/QFjXp9pNUHU

ずーっと頭真っ白でしたが、超楽しかったです。

終わってみて気が付いたけれど、説明すっ飛ばしポイントがいっぱいありました。ごめんなさい。

何を作ろうとしているのか?

作ろうとしているのは、Alternative Site LogoというロゴをSVGで好きにがちゃがちゃしたい人のためのブロックです。SVGを画像タグで扱うのではなくて、SVGタグ or インラインCSSで扱ったり、かんたんなアニメーションつけたり、色変えたりしたいなーっていうわがままブロックです。

ポイント解説

開発する方には、キタジマさんやハマノさんらのデバックの仕方や思考の手順が一番参考になると思うのでじっくりみていただきたいのですが、普通に観てると大分と放送事故感あふれる内容なので、何を悩んでどうしたか、をまとめておきたいと思います。

1. メディアップローダーとして何を使うか選定

「media uploader wordpress gutenberg」でググらずに公式GitHubの画像ブロックの中身を見ました。

WordPressのコンポーネントは沢山あるので、実際のコアブロックで何が使われているのかから調べた方が見当がつけやすいため最近はすぐGitHubを見ます。

gutenberg/edit.js at trunk · WordPress/gutenberg
https://github.com/WordPress/gutenberg/blob/trunk/packages/block-library/src/image/edit.js

を見て、つかってみることにしたのは<MediaPlaceholder />

gutenberg/packages/block-editor/src/components/media-placeholder at trunk · WordPress/gutenberg https://github.com/WordPress/gutenberg/tree/trunk/packages/block-editor/src/components/media-placeholder

で、とりあえず、見当がついたコンポーネントの動作を確認してみました。

コンポーネントをインポートして、普通にタグを書くだけで、UIの表示はできました!やったね!

次はSVG形式のmime typesを許可してあげればいいだけでしょ、と思っていたのですが。

2. 普通にデザインツールで書き出したままSVGファイルの形式がinvalidなのでmime types許可しただけだとアップロードできない

なので一旦SVG Supportという既存のプラグインで一旦SVGをアップロードできるようにする部分は肩代わりしてもらって。

SVG Support
https://github.com/wp-plugins/svg-support

今日のところは、アップロード機能だけをざっくり作ることにしてみました。

3. block.jsonのattributeに何を保存するか書く

まずはアップロードされたデータの受け取り側を用意します。

block.jsonのattributesの中に、最低限必要そうなidurlを用意しました。

block.jsonのattributesについてはこちら

block.jsonに以下を追記しました。

"attributes": {
		"url": {
			"type": "string"
		},
		"id": {
			"type": "number"
		}
	},

で、MediaPlaceholderで呼び出します。

export default function Edit({ setAttributes, attributes }) {
	const { url } = attributes;
	return (
		<div {...useBlockProps()}>
			<MediaPlaceholder
				onSelect={(el) => {
					setAttributes({ url: el.url });
				}}
				allowedTypes={['image/svg+xml']}
			/>
		</div>
	);
}

さくっとこんなにキレイに書けたら良いんですけど、なんちゃってなので、全然覚えられません。

4. eslintを使うとエラーを早く発見できます

ツールに頼りましょう。

wp-scriptsにeslintがすでに用意されているので、活用しましょう。create block した場合は以下のスクリプトが既に用意されています。

$ npm run lint:js

自動で修正できるところはしてもらうようにするには

$ npm run lint:js -- --fix

…linterが無いと生きていけない私と違って、みなさん、つよつよな人たちだからwatchしない派らしいですが、次回までにこのlintとbuildがsaveしたら走るようにwatchを書いておこうと思います。

で、無事にアップロードされた画像URLを受け取ることができました。MediaPlaceholderでちゃんとonSelectした時点でメディアライブラリに追加されるようですね。

ここでは、受け取った画像の表示機能はまだついていないので、コードの中にURLが入っているだけです。でも期待通りの動き。よしよし。

5. 既存のブロックの画像表示方法をチェックしてみる

ここで画像の表示方法をコアがどうしているかざっと見てみたのですが、画像ブロックの複雑さに目眩。サイトロゴブロックはまだちょっとシンプルだけれど、画像の編集機能があったりするのでなかなかゴージャスです。

ということで、とりあえず三項演算子でかんたんに分岐してimgタグで表示しちゃおっか?という話に。

6. 三項演算子でJSX内分岐

でこんな感じに。三項演算子についてはこちら。すぐに諳んじられないの恥ずかしかったー。

export default function Edit({ setAttributes, attributes }) {
	const { url } = attributes;
	return (
		<div {...useBlockProps()}>
			{url ? (
				<img src={url} alt="" />
			) : (
				<MediaPlaceholder
					onSelect={(el) => {
						setAttributes({ url: el.url });
					}}
					allowedTypes={['image/svg+xml']}
				/>
			)}
		</div>
	);
}

これで無事に、アップロードしたら表示されるようになりました🎉

7. 最後にsaveを忘れずに

よーし大体できましたよ。

最後にsaveを書いたら終わり!だったのにbuild忘れというぽかをやらかしました。

だから私にはwatchが必要なのだ…w

export default function save({ attributes }) {
	const { url } = attributes;
	if (!url) {
		return null;
	}
	return (
		<div {...useBlockProps.save()}>
			<img src={url} alt="" />
		</div>
	);
}

お疲れさまでした!ワチャワチャ言いながらも、2時間でまあまあ進んだほうなのではと思いますがいかがだったでしょうか?

次のIssue

  • 置いてけぼりのSVGアップロード機能を持たせて、自前でアップロードできるようにしたい
  • SVGタグをurlから引っこ抜いてタグで表示させたい

Issueはまだたくさんありますが、次に取り掛かるべきはこの辺りですかね。

ほんとはテスト駆動にしたいぞ

今回はtryだったので、手探りで書いてみましたが、次からはちゃんとテスト駆動にしたいですね!

5.9の追っかけに戻らないといけませんが、多分楽しすぎるので、このプロジェクトも続くと思います。続きをお楽しみに!

リポジトリはこちら:https://github.com/miminari/alternative-site-logo