Lazy Blocksで快適なカスタマイズを

1年くらい前まではWordPressのブロックエディタを毛嫌いしてクラシックエディタ用プラグインをわざわざ入れていたりしましたが、もはやブロックエディタ無しではWordPress案件はこなせないほど浸透してきたかんじなので、ブロックエディタの利用をデフォルトとして制作を進めるようになってきた、きょうこのごろ。

デフォルトの機能だけではどうしても対応しきれない部分も出てきたので、カスタムブロックを(なるべくお手軽に)導入する方法をイロイロ調べ、近頃はLazy Blocksというプラグインを利用するようになりました。このプラグインを使うと、これまでカスタムフィールドを自在に使いこなしてきたヒトなら、公式ドキュメントを参照しながらある程度自由にカスタムブロックを作ることができます。

使用に際して躓きがちだったところを、備忘録的に記載していきます。
躓くたびに記事が充実していく予定www

テキストエリア内改行

テキストエリアに入力した文章の改行が反映されない、とゆー指摘を受けて、echoの後にnl2brを付け足しました。

echo nl2br( $attributes['control_name] );

Advanced Custom Fieldsだと、改行をどのように扱うか管理画面内で設定できるのですが、Lazy Blocksにはそういう選択肢はなさそうです。

ちなみに、テーマファイルに書くテンプレートタグ、PHPの記法はフツーに使えます。

繰り返しフィールド

「関連記事」という見出しの下に、サイト内の関連記事を手動で入力するブロックが必要で、記事数は自由に設定したいということだったので、「Repeater」という種類のコントロールを作り、その中に記事へのリンクやテキスト等の子コントロールを用意しました。

<dl>
  <dt>関連記事</dt>
  <dd>
    <ul>

    <?php foreach ( $attributes [ 'control_name' ] as $inner ) : ?>

      <li>
        <a href="<?php echo esc_url($inner [ inner_control_name-url' ]); ?>">
          <dl>

            <?php $id=url_to_postid($inner [ 'inner_control_name-url' ]); ?>

            <dt><?php echo get_the_title($id); ?></dt>
            <dd><?php echo nl2br($inner [ 'inner_control_name-txt' ]); ?></dd>
          </dl>
        </a>
      </li>

    <?php endforeach; ?>

      </ul>
    </dd>
  </dl>

「URL」という種類のコントロールを使用すると、テキストを入力すると、サイト内の記事の候補を表示してくれます。記事タイトルは以下の関数でURLから取得できるので、入力欄は設けませんでした。

url_to_postid()

外部サイトの記事なども参照する場合は、記事タイトルの入力欄も設け、入力がある場合はソレを表示、ない場合はURLから取得するという方法が取れるかと思います。

画像ギャラリー

サムネイルをクリックすると、メイン画像がサムネイルと同じ画像に切り替わるという画像ギャラリーを固定ページ内に好きなだけ設置したい、ということだったので、専用のカスタムブロックを作りました。と言っても「Repeater」内に「Image」という子コントロールを設置しただけです。

実は「Gallery」というコントロールもあるのですが、これだとデフォルトで複数画像を登録するフィールドが作られるようです。こっちの方がUIがスッキリしていてよかったカモ…

<figure>
  <?php foreach ( $attributes ['control_name'] as $inner ) : ?>
  <img decoding="async" src="<?php echo esc_url($inner['inner_control_name']['url']); ?>" alt="">

  <?php break; ?>
  <?php endforeach; ?>

</figure>
<ul>

  <?php foreach ( $attributes ['control_name'] as $inner ) : ?>
  <li>
    <?php 
      echo wp_get_attachment_image( $inner['inner_control_name']['id'], 'thumbnail', false, array(
        'alt'   => "",
      )
    );
    ?>
  </li>
  <?php endforeach; ?>
</ul>
画像ギャラリー

「Image」というコントロールは、画像ID・画像URL・画像サイズなどを配列として取得し、それぞれ出力できるようになっています。

初めはimgタグ内のsrc属性に画像URLを出力していたのですが、ソレだとサムネイル部分にまで大きな画像が出力されてしまい、表示が遅くなっていたので、サムネイル部分はテンプレートタグwp_get_attachment_image()を使用し、thumbnailサイズの画像が出力されるように変更しました。

すると一つ問題が発生して、メイン画像が切り替わった時、サムネイルサイズの画像になってしまう、すなわちちっちゃい画像が引き伸ばされてボケボケの状態のものが表示されてしまうんですね(^_^;)

サムネイル画像には「-150×150」というサフィックスが常に付くので、ギャラリー用のスクリプトの方ででソレを削除したURLに置き換えるように変更しました。

が、例えばサムネイルをa要素で囲むようにマークアップを変更し、a要素のsrc属性にメイン画像のサイズとしてちょうどよい画像のURLを出力して、メイン画像のURLに置き換える形にしても良いかと思われます。ボタン的な役割の要素をa要素でマークアップするのはなんか嫌だったので、止めましたけども(であれば、span要素等のカスタムデータ属性に値を持たせればよいのかな。次はそうしよう…)。

ラジオボタンの使用

何種類かの画像が予め用意されていて、特定の画像に対して特定のキャプションを付けるカスタムブロックを作成しました。ラジオボタンのコントロールにラベルと値を設定し、「Output Format」で「Both (Array)」を選んでおくと、返り値が配列となり、ラベルと値のいずれも出力できるようになります。

キャプションとして「ラベル」の内容を出力し、値の方をファイル名の一部として出力し、テーマファイル内に用意した画像を表示するように設定しました。

<figure>
  <img decoding="async" src="<?php echo esc_url( get_template_directory_uri() ); ?&gt/images/img_<?php echo $attributes['control_name']['value']; ?>.png" alt="">
  <figcaption><?php echo $attributes['control_name']['label']; ?>  
 </figcaption>
</figure>
ラジオボタンコントロールのオプション

使用できるブロックを制限する場合

使用できるブロックの種類を制限してユーザビリティを向上させるケースも有るかと思いますが、その場合、使用するブロックをfunctions.phpに書く方法と、管理画面の「オプション(右上の3点リーダー)>ツール>ブロックマネージャー」でユーザーごとに表示するブロックを制限する方法があります。

前者の場合、Lazy Blocksで作ったカスタムブロックも個別に記述する必要があります。意外と忘れがちwww

function custom_allowed_block_types( $allowed_block_types, $editor_context ) {
  if ( ! empty( $editor_context->post ) ) {
    return array(
    'core/paragraph',
    'core/heading',
    'core/image',
    'lazyblock/control_name',
    );
  }
  return $allowed_block_types;
}
add_filter( 'allowed_block_types_all', 'custom_allowed_block_types', 10, 2 );

ブロック用のコードをテーマディレクトリ内に置く

layzy Blocksの出力については、管理画面内にソースコードを記載する方法と、テーマディレクトリ内にファイルを置いて管理する方法があります。

後者はカスタムフィールドを使用する時の状態と似ていますね。具体的には下記の場所にファイルを置いて、output methodで「Theme Template」を選択して保存すれば良いようです。

/wp-content/themes/{theme}/blocks/lazyblock-{blockname}/block.php

管理画面のコードエディタ上でCtrl+Xというショートカットを使用すると、画面の要素が全部消えてしまうという現象が発生して憮然とする事が多々ありましたし(リビジョンを使って復旧はできるのですが…)、テキストエディタ上で書くほうが何かと便利なので、今後はファイルとして管理するようにしようかな、と思っています。

Lazy Blocksの管理画面内でeditor-styleを無効にする

Lazy Blocksの管理画面がなんだか使いにくいなーと思っていたのですが、投稿用のエディタスタイルが当たっていたため、余白等が削除されてレイアウトが崩れていただけでした。

望ましい状態
崩れている状態

通常、エディタースタイルを読み込むときは、functions.phpに下記のように記載しますが

function my_after_setup_theme() {
  add_theme_support( 'editor-styles' );
  add_editor_style( 'css/editor-style.css' );
}
add_action( 'after_setup_theme', 'my_after_setup_theme' );

add_editor_style( 'css/editor-style.css' );部分を削除して、エディタースタイル用のファイル名をeditor-style-post.cssに変更し、下記の記述を追記しました。

function wpdocs_theme_add_editor_styles() {
  global $post;
  if ( stristr( $_SERVER['REQUEST_URI'], 'post-new.php' ) !== false ) {
    if ( isset( $_GET['post_type'] ) == false ) {
      $post_type = 'post';
    } else {
      $post_type = $_GET['post_type'];
    }
    add_editor_style( 'css/editor-style-' . $post_type . '.css' );
  }
  if ( stristr( $_SERVER['REQUEST_URI'], 'post.php' ) !== false && is_object( $post ) ) {
    add_editor_style( 'css/editor-style-' . get_post_type( $post->ID ) . '.css' );
  }
}
add_action( 'init', 'wpdocs_theme_add_editor_styles' );
add_action( 'pre_get_posts', 'wpdocs_theme_add_editor_styles' );

editor-style-post.cssのpostの部分は投稿タイプを取得して当てているので、投稿タイプごとにスタイルシートを用意してそれぞれに適用することもできます。 固定ページならeditor-style-page.cssというスタイルシートを作れば、その内容が管理画面に反映されるはずです。

参考:関数リファレンス/add editor style

WordPress本体のバージョンを最新にしたら、エラーが出るようになった(^_^;)

‘block_categories’、’allowed_block_types’というフィルターがWordPress5.8から非推奨となり、環境によっては(試した環境はphp7.4)LazyBlocksを有効にしていると投稿画面でエラーが出るようになってしまいました

Deprecated: block_categories の使用はバージョン 5.8.0 から非推奨になっています ! 代わりに block_categories_all を使ってください。

Deprecated: allowed_block_types の使用はバージョン 5.8.0 から非推奨になっています ! 代わりに allowed_block_types_all を使ってください。

修正依頼を出しておいたので、そのうち対応してくれると思うのですが、下記ファイルをちょこっと手直ししたらエラーは解消されました。

/wp-content/plugins/lazy-blocks/classes/class-blocks.php

66行目の’allowed_block_types’を’allowed_block_types_all’に変更

add_filter( 'allowed_block_types', array( $this, 'allowed_block_types' ), 10, 2 );
⇓
add_filter( 'allowed_block_types_all', array( $this, 'allowed_block_types' ), 10, 2 );

82行目の’block_categories’を’block_categories_all’に変更

add_filter( 'block_categories', array( $this, 'block_categories' ), 100 );
⇓
add_filter( 'block_categories_all', array( $this, 'block_categories' ), 100 );

‘allowed_block_types_all’の第二引数が $post から $block_editor_context に変わったので、投稿タイプの取得の方法も異なります。372~373行目を書き換えます

public function allowed_block_types( $allowed_block_types, $post ) {
        if ( 'lazyblocks' !== $post->post_type ) {
⇓
public function allowed_block_types( $allowed_block_types, $block_editor_context ) {
    if ( 'lazyblocks' !== $block_editor_context->post->post_type ) {