Open31

Block Bindings API についてしらべる

ちあきちあき

6.5時点でBlock Bindings APIが使えるブロックは

  • 画像ブロック
  • 段落ブロック
  • 見出しブロック
  • ボタンブロック

これだけ使えたら十分感はあるねえ

ちあきちあき

Block Bindings API使えばカスタムフィールドの値がブロックで使える。
例えばアーカイブページとかで会社名入れたい!ってときに会社名表示させる段落に紐づけておけば表示可能ってことかな? 🤔

ちあきちあき

地味にwp-env でファイル同期するの面倒なんだよな…。

テーマつくる→エクスポートする→ローカルに置く→置いたテーマを有効化する
テーマつくったらローカルにぴろって生えたらいいのに…。まあ、Localとかだとまた違ってくると思う

ちあきちあき

設定からカスタムフィールドを表示させる。これは多分プラグインとかでカスタムフィールド足したりするなら不要ではないかなー

ちあきちあき

会社名用のカスタムフィールドをつくる。

add_action( 'init', 'chiilog_register_meta_fields' );

function chiilog_register_meta_fields() {
	register_meta(
		'post',
		'company_name',
		array(
			'show_in_rest'      => true,
			'single'            => true,
			'type'              => 'string',
			'sanitize_callback' => 'wp_strip_all_tags'
		)
	);
}
ちあきちあき

今回はチュートリアル見ながらのお手軽でやっていくのでパネルで値入力

ちあきちあき
<!-- wp:paragraph {
	"metadata":{
		"bindings":{
			"content":{
				"source":"core/post-meta",
				"args":{
					"key":"company_name"
				}
			}
		}
	}
} -->
<p></p>
<!-- /wp:paragraph -->

これだけでデータ紐づけ完了!!!!!

ちあきちあき

content の部分はブロックによってかわる。画像ブロックだったら url とか alt とか。

ちあきちあき

段落タグからカスタムフィールドを更新したりはできないので注意。あくまで表示するためだけ。

ちあきちあき

詳細ページでは表示できたけど、アーカイブではさてさて…

ちあきちあき

もちろんクラスとか背景色とかは普通の段落タグとおなじように変更可能!
ただし、値が入ってなかったら出さない的な処理はデフォルトではできない。

ちあきちあき
  • データ紐づける対象はボタン
  • register_block_bindings_source で紐づけするデータをつくる
ちあきちあき

create-block いるかなと思ったけどブロック作るわけじゃないからプラグインファイルのみでいけそうかな

ちあきちあき
<!-- wp:buttons {"style":{"spacing":{"blockGap":"var:preset|spacing|30"}}} -->
<div class="wp-block-buttons"><!-- wp:button {"metadata":{"bindings":{"url":{"source":"chiilog/share-button","args":{"key":"x"}}}}} -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button">X</a></div>
<!-- /wp:button -->

<!-- wp:button {"metadata":{"bindings":{"url":{"source":"chiilog/share-button","args":{"key":"facebook"}}}}} -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button">Facebook</a></div>
<!-- /wp:button -->

<!-- wp:button {"metadata":{"bindings":{"url":{"source":"chiilog/share-button","args":{"key":"line"}}}}} -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button">LINE</a></div>
<!-- /wp:button -->

<!-- wp:button {"metadata":{"bindings":{"url":{"source":"chiilog/share-button","args":{"key":"hatena"}}}}} -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button">はてな</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons -->

ブロックはこんな感じで用意。urlにbindingつけたらブロックからリンクつけれなくなった

ちあきちあき

シェアボタンは現在の記事のURLがいるので、uses_contextpostIdとってきておく。

add_action( 'init', 'chiilog_register_block_bindings' );

function chiilog_register_block_bindings() {
	register_block_bindings_source( 'chiilog/share-button', array(
		'label'              => __( 'SNS', 'chiilog-share-button' ),
		'get_value_callback' => 'chiilog_sns_data_bindings',
		'uses_context'       => [ 'postId' ]
	) );
}

function chiilog_sns_data_bindings( $source_args, $block_instance ) {
	$current_post_id = $block_instance->context['postId'];

	// キーがない場合はなにもしない
	if ( ! isset( $source_args['key'] ) ) {
		return null;
	}
}
ちあきちあき

ああ、binding使わなくてもWP_HTML_Tag_Processorでやればいいのか。シェアボタンは基本_blankだし

ちあきちあき

はてないらんな…ページのリンクなしでつくれるじゃん

ちあきちあき
/**
 * SNSのシェアリンクを返す
 *
 * @param array $source_args
 * @param WP_Block $block_instance
 *
 * @return string|null
 */
function chiilog_sns_data_bindings( $source_args, $block_instance ) {
	$current_post_id = $block_instance->context['postId'];

	// キーがない場合はなにもしない
	if ( ! isset( $source_args['key'] ) ) {
		return null;
	}

	switch ( $source_args['key'] ) {
		case 'x':
			return 'https://twitter.com/intent/tweet?url=' . esc_url( get_permalink( $current_post_id ) ) . '&text=' . esc_attr( get_the_title( $current_post_id ) );
		case 'facebook':
			return 'https://www.facebook.com/sharer/sharer.php?u=' . esc_url( get_permalink( $current_post_id ) );
		case 'line':
			return 'https://social-plugins.line.me/lineit/share?url=' . esc_url( get_permalink( $current_post_id ) ) . '&text=' . esc_attr( get_the_title( $current_post_id ) );
		default:
			return null;
	}
}
ちあきちあき
add_filter( 'render_block_core/button', 'add_link_target_for_binding_button', 10, 2 );

function add_link_target_for_binding_button( $block_content, $block ) {
	$processor = new WP_HTML_Tag_Processor( $block_content );

	if ( isset( $block['attrs']['metadata']['bindings']['url']['source'] ) ) {
		$binding_source = $block['attrs']['metadata']['bindings']['url']['source'];
		if ( $binding_source === 'chiilog/share-button' ) {
			$processor->next_tag( array( 'class_name' => 'wp-block-button__link' ) );
			$processor->set_attribute( 'target', '_blank' );
		}
	}

	return $processor->get_updated_html();
}

こんな感じでつける