如何仅在WordPress特定Query区块变体存在时加载对应脚本?
解决WordPress FSE主题中Query区块变体的脚本按需加载问题
问题背景
我在开发WordPress FSE主题时,给core/query区块做了名为horizontal-query的变体,用来实现文章滑块功能。目前滑块需要的JavaScript脚本,只要页面里有任意core/query区块就会加载,但我希望只有当这个特定变体存在时才加载脚本。另外当前block-variations.js和滑块脚本是分开enqueue的,想找更优的实现方式。
当前代码:
block-variations.js
wp.blocks.registerBlockVariation("core/query", { name: "horizontal-query", title: "Scrolling Query Loop", description: "Displays the Query Loop with horizontal scrolling and navigation buttons.", isActive: ["namespace"], attributes: { namespace: "hs_query_loop", className: "hs-query-loop", }, scope: ["inserter", "transform"], });
functions.php(当前版本)
$id = get_the_ID(); if (has_block('core/query', $id)) { wp_enqueue_script( 'hs-query', get_template_directory_uri() . '/assets/js/scrolling-query-loop.js', array('jquery'), wp_get_theme()->get( 'Version' ), true, ); }
解决方案
1. 精准检测特定变体是否存在
原来的has_block('core/query')只能判断页面有没有Query区块,无法区分变体。我们可以遍历页面所有区块,检查是否存在带有你定义的namespace或className的Query区块:
替换functions.php中的脚本加载逻辑:
function enqueue_hs_query_script() { $post_id = get_the_ID(); if ( ! $post_id ) return; // 获取页面的区块内容并解析 $post_content = get_post_field( 'post_content', $post_id ); $blocks = parse_blocks( $post_content ); $has_hs_query = false; // 遍历所有区块,检查目标变体 foreach ( $blocks as $block ) { if ( 'core/query' === $block['blockName'] ) { // 检查namespace是否匹配 if ( isset( $block['attrs']['namespace'] ) && 'hs_query_loop' === $block['attrs']['namespace'] ) { $has_hs_query = true; break; } // 或者检查className是否包含目标类名 if ( isset( $block['attrs']['className'] ) && str_contains( $block['attrs']['className'], 'hs-query-loop' ) ) { $has_hs_query = true; break; } } // 递归检查嵌套区块(比如Query在容器区块里的情况) if ( ! empty( $block['innerBlocks'] ) ) { $has_hs_query = check_inner_hs_query_blocks( $block['innerBlocks'] ); if ( $has_hs_query ) break; } } // 只有变体存在时才加载脚本 if ( $has_hs_query ) { wp_enqueue_script( 'hs-query', get_template_directory_uri() . '/assets/js/scrolling-query-loop.js', array('jquery'), wp_get_theme()->get( 'Version' ), true ); } } // 辅助函数:递归检查嵌套区块 function check_inner_hs_query_blocks( $inner_blocks ) { foreach ( $inner_blocks as $block ) { if ( 'core/query' === $block['blockName'] ) { if ( isset( $block['attrs']['namespace'] ) && 'hs_query_loop' === $block['attrs']['namespace'] ) { return true; } if ( isset( $block['attrs']['className'] ) && str_contains( $block['attrs']['className'], 'hs-query-loop' ) ) { return true; } } if ( ! empty( $block['innerBlocks'] ) ) { if ( check_inner_hs_query_blocks( $block['innerBlocks'] ) ) { return true; } } } return false; } add_action( 'wp_enqueue_scripts', 'enqueue_hs_query_script' );
2. 优化区块变体脚本的加载
block-variations.js只需要在编辑器界面加载(后台编辑、站点编辑器),不需要加载到前端,所以可以调整其加载逻辑:
在functions.php中添加:
function enqueue_theme_block_variations() { // 仅在编辑器环境加载变体脚本 wp_enqueue_script( 'theme-block-variations', get_template_directory_uri() . '/block-variations.js', array( 'wp-blocks', 'wp-element' ), // 依赖区块编辑器的核心脚本 wp_get_theme()->get( 'Version' ), true ); } // 只在区块编辑器界面触发这个钩子 add_action( 'enqueue_block_editor_assets', 'enqueue_theme_block_variations' );
内容的提问来源于stack exchange,提问作者MarioGoodBad
相关产品推荐
相关产品推荐

