0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WordPressのブロックテーマで各投稿のカスタムフィールドを表示する(2024年8月時点)

Posted at

はじめに

WordPressはサイト全体を投稿本文のように編集できる「ブロックテーマ」に本格的に移行しています。
多くの資料がありますが、カスタムフィールド(投稿メタ)の表示に関する情報が少ないです。

現実には、画像のようなゴリッゴリのカスタムフィールドを多用したサイトを運用していて、頭を抱えている人も多いのではないかと思います。そのような人の一助となれば幸いです。

blocktheme_binding_02.jpg

カスタムフィールドを表示することは、できます。
が、この記事を書いている時点では難易度が高めです。また、仕様が変わる可能性も高いです。

読んでいるあなたがWordPressについて常時学習する時間が取れない、納品後の改修ができない状況であれば、他のCMSへの乗り換えを強く勧めます。

暫定措置

ノーコードで表示する

「Snow Monkey Blocks」プラグインには、カスタムフィールドの内容を表示できるブロックがあります。

ただし表示できるのは文字列だけで、画像カスタムフィールドは画像IDが表示されてしまうため使用できません。出力されるコードはdiv要素となります。

<div class="smb-custom-field wp-block-snow-monkey-blocks-custom-field">
	カスタムフィールドに入力した情報
</div>

旧来のコードのまま表示する

「Custom Blocks Constructor – Lazy Blocks」は、旧来のWordPressのテーマのコードからブロックを作成できます。

Block Bindings APIを使用する

ここからは今後のWordPressの推薦、「ブロックバインディングAPI」を使用する方法の解説です。バージョン6.6を使用している前提です。
お急ぎの方は4.まで飛ばすことができますが、おそらく後悔します。

1. Block Bindings APIとは

テンプレートに書いてあるブロックに外部情報を関連付けて、置き換えられる機能です。例として以下のようなことができます。

  • クエリループ内の投稿テンプレートや、各記事に配置したブロックの…
    • 段落を、投稿内のカスタムフィールドに登録した文字で置き換える
    • 画像のURLを、投稿内のカスタムフィールドにアップロードした画像のURLで置き換える
    • ボタンのリンク先を、投稿内のカスタムフィールドに登録したURLで置き換える

2. 置き換えられる値の制限

記事を書いている時点で、置き換えができるブロックは画像、段落、見出し、ボタンに制限されています。また、見出しと段落以外は全体のHTMLを置き換えることはできません。つまり、投稿ループ全体をa要素で囲むなど、大幅な加工はできません。

詳細は以下を参照ください。

例えば画像は、以下の3つの属性値のみ可能です。

  • 画像のURL url
  • 画像の代替テキスト alt
  • 画像のタイトル title

このため、SEOやスライドショーで表示するために、altやtitleも書き換えたい場合は、関連付けをこれらにも行わなくてはなりません。この記事ではURLの差し替えのみ解説します。

3. ACFに関する注意

Advanced Custom Fields(以降、ACF)プラグインはWordPress公式のカスタムフィールドとは規格が異なるので、後述の core/post-meta では表示できません。また、ブロックエディタ内では表示を確認できません。

「6. 画像ブロックを置き換える関数を追加する」の解説は、WordPress公式のカスタムフィールド前提で解説しています。もしかするとACFの画像ブロックだともっと簡単に表示できるかもしれません。この記事を書いている時点で未検証です。すみません。


以降、文字、画像のバインディングを解説していきます。

4. カスタムフィールドをブロックが参照できるようにする

ACFでカスタムフィールドを作成している場合は、この作業は不要なので飛ばしてください。

現在使用しているテーマの functions.php にコードを追記して、ブロックに関連付けたいカスタムフィールドを登録してください。
以下のサンプルコードでは投稿タイプ sightseeing に、カスタムフィールド sightseeing_catch, sightseeing_thumbnail を関連付けています。

add_action( 'init', 'mysite_register_post_meta' );
if ( ! function_exists( 'mysite_register_post_meta' ) ) {
	function mysite_register_post_meta() {
		register_post_meta(
			'sightseeing',
			'sightseeing_catch',
			array(
				'show_in_rest' => true,
				'sanitize_callback' => 'sanitize_text_field',
				'single' => true
			)
		);
		register_post_meta(
			'sightseeing',
			'sightseeing_thumbnail',
			array(
				'show_in_rest' => true,
				'sanitize_callback' => 'sanitize_text_field',
				'single' => false
			)
		);
	}
}
  • 以降、 mysite はテーマ名などに置き換えてください
  • この作業は、将来のバージョンアップで不要になってくれればいいなあと期待しています

入力データの無害化 sanitize_callback はこちらの記事が詳しいです。

5. 文字列フィールドを表示する

画像を置き換えたい場合は、この項は飛ばしてください。

表示したいテンプレートの編集画面へ移動し、右側の詳細メニューから「コードエディター」に切り替えます。
(実はテーマのテンプレートHTMLを直接編集する手もありますが、ここでは割愛します)

スクリーンショット 2024-08-04 12.08.49.jpg

カスタムフィールドを表示したい段落ブロックを探します。
以下のようになっているはずなので

<!-- wp:paragraph -->
<p>これはキャッチコピー</p>
<!-- /wp:paragraph -->

開始タグを以下の通り書き換えてください。 サンプルコードでは key にさっき関連付けたカスタムフィールド名 sightseeing_catch を指定しています。

<!-- wp:paragraph {
  "metadata":{
    "bindings":{
      "content":{
        "source":"core/post-meta",
        "args":{
          "key":"sightseeing_catch"
        }
      }
    }
  }
} -->

ACFの場合は source の値を以下の通り acf/field としてください。

<!-- wp:paragraph {
  "metadata":{
    "bindings":{
      "content":{
        "source":"acf/field",
        "args":{
          "key":"sightseeing_catch"
        }
      }
    }
  }
} -->

編集後、コードエディタを閉じると、段落ブロックが編集できなくなり、文字列がカスタムフィールドに置き換わっているはずです。

6. 画像ブロックを置き換える関数を追加する(前半)

現在使用しているテーマの functions.php に以下のコードを追記してください。

register_block_bindings_source の第一引数 mysite/image は控えておいてください。

add_action( 'init', 'mysite_register_block_bindings' );
function mysite_register_block_bindings() {

	register_block_bindings_source( 'mysite/image', array(
		'label' => 'mysite_image',
		'get_value_callback' => 'mysite_image_binding',
		'uses_context' => [ 'postId' ]
	) );

}

register_block_bindings_source 関数

ブロックの source に第一引数の文字列が指定されていたときだけ、第二引数の get_value_callback の値の名前の関数を実行します。 uses_context で、その関数に投稿のIDを渡しています。

実行関数 mysite_image_binding が必要になることがわかります。

7. 画像ブロックを置き換える関数を追加する(後半)

続けて以下のコードを追記してください。 $image_src には画像がなかったときのノーイメージのURLを記述してください。

function mysite_image_binding( $source_args, $block_instance ) {
	$image_src = 'https://mydomain/path-to-theme/noimage.png';
	if($block_instance->context['postId'] && $source_args['key']) {
		$image_src = wp_get_attachment_image_url( get_post_meta( $block_instance->context['postId'], $source_args['key'], true ), 'large' );
	}
	return esc_url($image_src);
}

ここでは、カスタムフィールドの画像URLを取得しています。最終行の return の値がブロックに置き換える内容となります。

8. 画像ブロックを表示する

表示したいテンプレートの編集画面へ移動し、右側の詳細メニューから「コードエディター」に切り替えます。

カスタムフィールドを表示したい画像ブロックを探します。
開始タグが以下のようになっているはずなので

<!-- wp:image {(ブロックの設定値が書かれている)} -->

以下の通り書き換えてください。 サンプルコードでは source に控えておいたregister_block_bindings_source の第一引数 mysite/imagekey にさっき関連付けたカスタムフィールド名 sightseeing_thumbnail を指定しています。

<!-- wp:image {
  "metadata":{
    "bindings":{
      "url":{
        "source":"mysite/image",
        "args":{
          "key":"sightseeing_thumbnail"
        }
      }
    }
  },
  (ブロックの設定値が書かれている)
} -->

編集後、コードエディタを閉じると、画像ブロックが編集できなくなり、公開画面の画像がカスタムフィールドに置き換わっているはずです。

「7. 画像ブロックを置き換える関数を追加する(後半)」で、 $source_args['key'] という変数が出てきました。実はここには、ブロックの key で指定したカスタムフィールド名が渡されています。
投稿IDとカスタムフィールド名を参照して、画像のURLを取得して置き換える、という仕組みです。

おわりに

WordPressのブロックテーマで、各投稿のカスタムフィールドを表示する手順は以上です。繰り返しますが、この記事の内容も古い or 間違いがあるかもしれません。コメントでご指摘いただけますと幸いです。

他にもよくあるカスタマイズとして、「カスタムフィールドに入力したURLをボタンのリンク先にする」がありますが、画像フィールドと同じ手順で実装できるので割愛しました。

なお、本文の特定のブロックのHTMLを、一覧ページにそのまま表示することも可能です。記事を書いている時点では、やや魔改造じみたカスタマイズになりますが、今後のバージョンアップによっては、クエリループの検索条件に使用しないカスタムフィールドは不要となるかもしれません。

謝辞

この記事は下記を始めとした、多数のドキュメントを参考にさせていただきました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?