画面をスクロールすると、画像がフェードインで表示するようにカスタマイズします。フェードイン用のスクリプトとスタイルは画像ブロックがない場合はフロントに読み込ませないようにし軽量化を図ります。
コンテンツ
JavaScriptとCSSファイルを「登録」する
JavaScriptとCSSファイルを任意のタイミングで利用できるように、準備段階として「登録」します。
namespace BlockDevelopersCookbook;
add_action('wp_enqueue_scripts', __NAMESPACE__ . '\register_custom_js_script');
function register_custom_js_script() {
$js_file = plugin_dir_path(__FILE__) . '/build/index.asset.php';
if (file_exists($js_file)) {
$js_assets = include $js_file;
wp_register_script(
'custom-script-for-code-block',
plugin_dir_url(__FILE__) . '/build/index.js',
$js_assets['dependencies'],
$js_assets['version'],
true
);
wp_register_style(
'test-styles',
plugin_dir_url(__FILE__) . '/build/index.css',
array(),
$js_assets['version'],
);
}
具体的にはwp_register_script()
や wp_enqueue_script()
を使用してあとで呼び出すファイルの内容を準備し、wp_enqueue_scripts
にフックします。
wp_enqueue_scripts
フックに関数を登録しても、その関数の中で wp_enqueue_script()
または wp_enqueue_style()
を呼ばなければ、スクリプトやCSSは読み込まれない。
wp_enqueue_scriptsフックの中で呼べる関数
JavaScript も CSS も、「登録」や「読み込み」に使うフックは wp_enqueue_scriptsになる。
ステップ | 関数 | 目的 |
---|---|---|
登録 | wp_register_script wp_register_style | あとで使うために準備する |
読み込み | wp_enqueue_script wp_enqueue_style | 実際にブラウザでスクリプトを読み込む |
特定のブロックがページ上に存在するときだけJavaScriptとCSSファイルを読み込む
add_filter('render_block', __NAMESPACE__ . '\enqueue_files_for_core_blocks', 10, 2);
function enqueue_files_for_core_blocks($block_content, $block) {
if ('core/cover' === $block['blockName'] || 'core/image' === $block['blockName']) {
$tag = new \WP_HTML_Tag_Processor($block_content);
if ($tag->next_tag()) {
$tag->add_class('fader');
}
$block_content = $tag->get_updated_html();
wp_enqueue_script('custom-script-for-code-block');
wp_enqueue_style('test-styles');
}
return $block_content;
}
特定のブロックが使われているかどうかを確認し、そのブロックが使われているページだけにスクリプトを読み込むため、render_block
フィルターを使う。
render_block
フィルター
- ブロックが レンダリングされるたびに実行されるフィルター
- 第1引数にブロックのHTML、第2引数にブロック情報の配列が渡される
- 各ブロックごとに呼び出されるため、その場でスクリプトを読み込ませる判断ができる
add_filter( 'render_block', __NAMESPACE__ . '\enqueue_files_for_core_blocks', 10, 2 );
処理の流れ
1. 関数定義
function enqueue_files_for_core_blocks( $block_content, $block ) {
$block_content
: ブロックのHTML(文字列)$block
: ブロックの情報(連想配列)→['blockName' => 'core/image', ...]
など
2.ブロックタイプをチェック
if ( 'core/cover' === $block['blockName'] || 'core/image' === $block['blockName'] ) {
core/cover
やcore/image
ブロックがあればスクリプトとCSSを読み込む
3.HTML にクラスを追加(オプションの演出)
$tag = new \WP_HTML_Tag_Processor( $block_content );
if ( $tag->next_tag() ) {
$tag->add_class( 'fader' );
}
$block_content = $tag->get_updated_html();
- WordPress 6.2 以降で使える
WP_HTML_Tag_Processor
クラスを使って、 - ブロックのHTMLに
fader
クラスを付加 - これは、アニメーションやCSSの指定に使う想定
4.スクリプトとスタイルを読み込み
wp_enqueue_script( 'custom-script-for-core-block' );
wp_enqueue_style( 'test-styles' );
- あらかじめ
wp_register_script()
などで登録しておいたスクリプトを読み込む - 読み込みは このブロックがあったページだけ になる
5.最後に、変更後のHTMLを返す
return $block_content;
- フィルターは常に内容を返す必要がある
- これを忘れるとブロックの出力が消える
各ブロックに専用のフィルターを使用する
render_blockフックの代わりに、render_block_coreフックを使用することもできる
add_filter('render_block_core/cover', __NAMESPACE__ . '\enqueue_files_for_core_blocks', 10, 2);
add_filter('render_block_core/image', __NAMESPACE__ . '\enqueue_files_for_core_blocks', 10, 2);
function enqueue_files_for_core_blocks($block_content, $block) {
$tag = new \WP_HTML_Tag_Processor($block_content);
if ($tag->next_tag()) {
$tag->add_class('fader');
}
$block_content = $tag->get_updated_html();
wp_enqueue_script('custom-script-for-code-block');
wp_enqueue_style('test-styles');
return $block_content;
}
render_block は 各ブロックごとに複数回呼ばれる
render_block
は 各ブロックごとに複数回呼ばれる ので、無駄な enqueue_*
呼び出しが発生している。まず確認してみよう
add_filter('render_block', __NAMESPACE__ . '\enqueue_files_for_core_blocks', 10, 2);
function enqueue_files_for_core_blocks($block_content, $block) {
// 追記
if (isset($block['blockName'])) {
echo '<!-- Rendering block: ' . esc_html($block['blockName']) . ' -->';
}
if ('core/cover' === $block['blockName'] || 'core/image' === $block['blockName']) {
$tag = new \WP_HTML_Tag_Processor($block_content);
if ($tag->next_tag()) {
$tag->add_class('fader');
}
$block_content = $tag->get_updated_html();
wp_enqueue_script('custom-script-for-code-block');
wp_enqueue_style('test-styles');
}
return $block_content;
}
その結果、開発者ツールにコメントが表示される。
<!-- Rendering block: core/image -->
また、別の方法では、デバッグモードを活用するため、wp-config.phpでデバッグモードを有効にし、エラーログをファイルに出力する設定にする。wp-content/debug.logが自動生成されログが記録されていく。
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false ); // ← これで画面には何も出ない
完成形
namespace BlockDevelopersCookbook;
add_action('wp_enqueue_scripts', __NAMESPACE__ . '\register_custom_js_script');
function register_custom_js_script() {
$js_file = plugin_dir_path(__FILE__) . '/build/index.asset.php';
if (file_exists($js_file)) {
$js_assets = include $js_file;
wp_register_script(
'custom-script-for-code-block',
plugin_dir_url(__FILE__) . '/build/index.js',
$js_assets['dependencies'],
$js_assets['version'],
true
);
wp_register_style(
'test-styles',
plugin_dir_url(__FILE__) . '/build/index.css',
array(),
$js_assets['version'],
);
}
}
add_filter('render_block_core/cover', __NAMESPACE__ . '\enqueue_files_for_core_blocks', 10, 2);
add_filter('render_block_core/image', __NAMESPACE__ . '\enqueue_files_for_core_blocks', 10, 2);
function enqueue_files_for_core_blocks($block_content, $block) {
$tag = new \WP_HTML_Tag_Processor($block_content);
if ($tag->next_tag()) {
$tag->add_class('fader');
}
$block_content = $tag->get_updated_html();
wp_enqueue_script('custom-script-for-code-block');
wp_enqueue_style('test-styles');
return $block_content;
}