使用WP_Query的acf/load_field钩子导致页面属性框为空
问题:ACF字段填充代码导致页面属性框为空
我编写了一段代码,用于将自定义文章类型Video的ID(作为值)和标题(作为标签)填充到ACF复选框列表中。该功能可正常输出列表,但启用后会导致页面编辑界面的页面属性框为空——没有父页面或模板下拉选项。移除if( $videos->have_posts() )代码段后,问题消失;仅移除循环内代码无法解决问题。
完整代码
if ( !function_exists('populate_available_videos') ): add_filter('acf/load_field/name=available_videos', 'populate_available_videos'); function populate_available_videos( $field ){ // reset choices $field['choices'] = array(); $args = array( 'post_type' => 'video', 'posts_per_page' => -1, 'post_status' => 'publish', 'orderby' => 'menu_order', ); $videos = new WP_Query($args); // Removing this loop fixes the error if( $videos->have_posts() ) : while( $videos->have_posts() ) : $videos->the_post(); // Removing just this does not fix the error $field['choices'][get_the_ID()] = get_the_title(); endwhile; wp_reset_postdata(); endif; return $field; } endif;
错误表现
页面编辑界面的页面属性区域完全为空,既没有父页面选择下拉框,也没有模板选择下拉框。
已尝试的解决方法
- 移除
wp_reset_postdata() - 将
wp_reset_postdata()替换为wp_reset_query() - 修改变量名
$videos
解决方案
问题根源在于the_post()方法会修改WordPress全局的$post对象,而页面属性框的渲染逻辑同样依赖这个全局对象。即便调用了wp_reset_postdata(),在ACF字段加载的时机下,全局状态可能无法正确恢复,从而干扰页面属性的正常渲染。
正确的做法是避免使用the_post()循环,直接遍历查询结果的posts数组,不触碰全局$post:
修改后的代码:
if ( !function_exists('populate_available_videos') ): add_filter('acf/load_field/name=available_videos', 'populate_available_videos'); function populate_available_videos( $field ){ // 重置选项 $field['choices'] = array(); $args = array( 'post_type' => 'video', 'posts_per_page' => -1, 'post_status' => 'publish', 'orderby' => 'menu_order', ); $videos = new WP_Query($args); // 直接遍历posts数组,不修改全局post对象 if ( !empty($videos->posts) ) { foreach ( $videos->posts as $video_post ) { $field['choices'][$video_post->ID] = $video_post->post_title; } } // 重置查询状态(可选,但养成好习惯) wp_reset_postdata(); return $field; } endif;
原理说明
通过直接访问$videos->posts中的文章对象,我们可以直接获取ID和标题,完全不需要调用the_post()来切换全局上下文。这种方式不会干扰任何依赖全局$post的功能,自然就解决了页面属性框为空的问题。
内容的提问来源于stack exchange,提问作者WickedDice
相关产品推荐
相关产品推荐

