WordPress钩子提前触发致Gutenberg块注册不全的解决咨询
问题分析
你的核心问题是:部分自定义ACF块未注册,调试发现acf/init钩子在块文件循环加载完成前就已触发,导致后续文件中的add_action('acf/init')来不及绑定执行。
触发原因有两个:
- 你使用的
glob(__DIR__ . '/blocks/*/**.php')会同时加载gutenberg-init.php和render.php,若某个render.php中调用了ACF函数(如get_field),会触发ACF提前初始化,直接执行acf/init钩子。 - 直接在
functions.php根级别执行循环,未利用WordPress钩子机制确保加载时机早于acf/init。
解决方案
方案一:调整文件加载顺序(最简单)
先加载所有块的初始化文件,确保所有add_action('acf/init')完成绑定后,再加载可能调用ACF函数的渲染文件:
// 优先加载所有块的初始化文件 foreach (glob(__DIR__ . '/blocks/*/gutenberg-init.php') as $file) { include_once($file); } // 再加载渲染文件 foreach (glob(__DIR__ . '/blocks/*/render.php') as $file) { include_once($file); }
方案二:利用WordPress钩子确保加载时机
将文件加载逻辑绑定到after_setup_theme钩子(该钩子在acf/init之前触发),确保所有块文件在ACF初始化前加载完成:
add_action('after_setup_theme', 'load_all_custom_blocks', 10); function load_all_custom_blocks() { // 加载初始化文件 foreach (glob(__DIR__ . '/blocks/*/gutenberg-init.php') as $file) { include_once($file); } // 加载渲染文件 foreach (glob(__DIR__ . '/blocks/*/render.php') as $file) { include_once($file); } }
方案三:统一收集配置批量注册(最健壮)
彻底避免加载顺序问题,先收集所有块的配置,再在acf/init中批量注册:
- 每个块文件夹下创建
block-config.php,返回块配置数组:
// blocks/your-block/block-config.php return [ 'name' => 'your-block', 'title' => '自定义块', 'render_callback' => function($block) { include(__DIR__ . '/render.php'); }, // 其他块配置(如icon、category等) ];
- 在
functions.php中收集配置并批量注册:
$custom_blocks = []; // 收集所有块配置 foreach (glob(__DIR__ . '/blocks/*/block-config.php') as $file) { $config = include($file); if (is_array($config)) { $custom_blocks[] = $config; } } // 在ACF初始化时批量注册块 add_action('acf/init', function() use ($custom_blocks) { foreach ($custom_blocks as $block_config) { acf_register_block_type($block_config); } });
内容的提问来源于stack exchange,提问作者marks
相关产品推荐
相关产品推荐

