ところで、ブロックパターン(以下、「パターン」という)は PHP が書けます。
シンプルなパターン
たとえば、パターンファイルに次のような PHP を書いてエディターで追加すると、エディター側、フロント側の両方でサイト名が表示されます。
<!-- wp:paragraph -->
<p><?php echo esc_html( get_bloginfo( 'name' ) ); ?></p>
<!-- /wp:paragraph -->
上のようなシンプルな値を表示するパターンなら、わりと使い勝手がいいです。
条件分岐があるパターン
では、次のように if 文などを使って条件分岐させるパターンを投稿のエディター内に追加した場合、どうなるでしょうか(このパターンが実用性あるかどうかは置いておく)。
$post_id = get_the_ID();
if ( $post_id ) {
?>
<!-- wp:paragraph -->
<p><?php echo absint( $post_id ); ?></p>
<!-- /wp:paragraph -->
<?php
} else {
?>
<!-- wp:paragraph -->
<p>no post_id</p>
<!-- /wp:paragraph -->
<?php
}
エディター側の結果
「no post_id」が表示されます。
フロント側の結果
「no post_id」が表示されます。
考察
エディター内では、変数「$post_id」の有無が評価され、条件分岐された結果が表示されている、ということになります。
なので、エディター内では変数「$post_id」に格納する「get_the_ID()」の結果が取得できない、ということですね。
フロント側では PHP が動作すれば「get_the_ID()」の結果が取得できるはずです。しかし、エディター側と同じ結果が表示される理由は、エディター側でパターンを追加し、保存したタイミングで、条件分岐された結果に上書きされてしまうからです。
条件分岐を絡めたパターンは作れないのか?
上のような結果を受け試行錯誤していた当時、今よりもさらに情報がなく、自ら試して答えを見つけるしかありませんでしたが「エディター側でパターンを追加し「保存」すると上書きされるのでダメ。ってことは、テンプレートやテンプレートパーツ内にあらかじめパターンを読み込んでおけばいけるんじゃないか?」という検証をしてみました。
結果は、フロント側では期待する投稿 ID が表示されます。が、エディター側では依然として「no post_id」表示されます。
フロント側で正しい結果が表示されたので、一歩進みました。「とりあえずフロント側で動けばいいか〜」という考え方もできるので、テンプレートやテンプレートパーツにパターンをあらかじめ読み込んでおく方法でもいいかもですが、問題はあります。
この方法の問題点
たとえば、ブロックの並び替えなどを行なって編集した内容を「保存」すると、条件分岐された結果が上書きされてしまいます。
パターンをブロックのように扱って自由に並び替えたりできるのがブロックテーマのいいところ、サイトエディターのいいところですよね。
なので、例に挙げたような条件分岐を含んだパターンをあらかじめテンプレートやテンプレートパーツで読み込んでいる場合、エディター側で上書きされないよう、パターンファイルのコードを直接編集することになります。これはけっこうメンテナンス性が悪く、わかりやすい問題点です。
ダイナミックブロックとして作り直した
というわけで「もっとブロックの恩恵を受けたい!」ということで、条件分岐が絡んだパターンは廃止して、すべてダイナミックブロックに変換しました。
普段の年末年始は永遠にゲームをして過ごすんですが、なぜかやる気が出て、この Hakoniwa 公式サイトで機能している「ライセンス管理」「プロフィール更新」「Stripe との連携と Webhook」などのパターンをすべてダイナミックブロックにしました。
ダイナミックブロックなら、エディター側とフロント側で表示内容を変えられるので、たとえばエディター側で「フロント側で投稿 ID を表示します。」みたいな表示をさせておくのも一つの選択だと思います。
エディター側、フロント側の両方で差異の少ない表示をするためには、特にエディター側の工数がそれなりにかかります。「本当にエディター側で同じような表示が必要なのかどうか」を十分検討することが重要だな、という考えに至っています。
- 作ろうとしているコンテンツをパターン化できるかどうか
- 条件分岐を絡めた複雑なプログラムを動かす場合はパターンではなく、ダイナミックブロックにしてみるのはどうか
- ダイナミックブロックを作る際、エディター側、フロント側で差異の少ない画面を提供するべきかどうか
などの思考ができると、開発方針が定まりやすくなります。
ダイナミックブロックの作り方
create-block を使うと結構ラクに作れます。パッケージも更新されてて、コマンド実行時に「作るブロックは動的(dynamic)か、静的(static)か?」という感じで聞かれ、ダイナミックブロックの雛形を作ってくれます。
おまけ:Block Bindings API で作ってもいい
試しに Block Bindings API の register_block_bindings_source を使ってみましたが、けっこう調子いいです。ダイナミックブロックの代案としても覚えておいていいかもです。
まとめ
なるべくわかりやすくしたかったので「条件分岐が絡んだパターン」を例に挙げましたが、パターンにおいては、エディター側とフロント側でデータの取得方法や扱いの違いにより、思ったような結果が得られないことがあります。
今のところ、ダイナミックブロックにしてしまった方がいいな、という結論です。
少し踏み込んだパターンの体験談でした!