
在 WordPress 主题模板中已执行的查询(如 get_terms)无法直接传递给 Gutenberg 自定义区块或短代码;但可通过 set_query_var() 在模板中预设变量,并在区块/短代码中安全读取,实现数据复用,避免重复查询。
在 wordpress 主题模板中已执行的查询(如 `get_terms`)无法直接传递给 gutenberg 自定义区块或短代码;但可通过 `set_query_var()` 在模板中预设变量,并在区块/短代码中安全读取,实现数据复用,避免重复查询。
在开发主题时,我们常需在页面头部提前获取分类术语(如子分类)、文章列表等数据用于导航或摘要展示。然而,当这些数据还需在 Gutenberg 编辑器内容流的中间位置(例如某个自定义卡片区块内)再次呈现时,传统方式往往导致同一查询被执行两次——不仅降低性能,还可能因缓存不一致引发显示异常。
WordPress 提供了一个轻量且可靠的机制:set_query_var() 与 get_query_var() 配合使用,可在模板上下文(Template Context)中跨作用域共享变量。关键在于:Gutenberg 区块渲染(无论是 ACF 块、原生 PHP 渲染块,还是短代码回调)均运行在同一主查询生命周期内,因此可访问通过 set_query_var() 设置的变量。
✅ 正确实践步骤如下:
-
在页面模板(如 page.php 或 single.php)中设置变量
在调用 the_content() 之前,将已查询结果存入全局查询变量:
<?php // 页面模板中:已执行一次查询
$children_terms = get_terms([
'taxonomy' => $taxonomy_name,
'hide_empty' => false,
'parent' => $related_product_term->term_id,
'fields' => 'all_with_object_id', // 推荐显式指定字段
]);
// 安全写入查询变量(自动转义不在此处理,由后续消费方负责)
set_query_var('page_children_terms', $children_terms);
?>
-
在自定义区块或短代码中读取并使用
例如,在 ACF 自定义区块的 PHP 模板文件(acf-blocks/children-cards/block.php)中:
<?php // 安全读取,提供默认值防止未定义警告
$terms = get_query_var('page_children_terms', []);
if (!is_array($terms) || empty($terms)) {
return; // 或输出占位提示
}
foreach ($terms as $term) :
$thumbnail_id = get_term_meta($term->term_id, 'thumbnail_id', true);
$thumbnail_url = $thumbnail_id ? wp_get_attachment_image_url($thumbnail_id, 'medium') : '';
?>
<article class="term-card"><?php if ($thumbnail_url) : ?><img src="<?php%20echo%20esc_url(%24thumbnail_url);%20?>" alt="<?php echo esc_attr($term->name); ?>" style="max-width:90%" style="max-width:90%"><?php endif; ?><h3>
<?php echo esc_html($term->name); ?></h3>
<p><?php echo esc_html($term->description); ?></p>
</article><?php endforeach; ?>
⚠️ 注意事项:
- set_query_var() 是 WordPress 核心函数,仅在主查询生命周期内有效(即模板加载阶段),不适用于 AJAX 或 REST API 上下文;
- 不要将敏感数据(如数据库原始结果集、用户凭证)直接存入查询变量;始终对输出做 esc_*() 转义;
- 若使用 Block.json + React 渲染的动态区块,请改用 wp_add_inline_script() 注入 JSON 数据至前端,后端 PHP 仍需通过 wp_localize_script() 提前准备;
- 短代码函数中同样适用 get_query_var(),但需确保短代码执行时机晚于 set_query_var() 调用(即在 the_content() 内触发)。
该方案简洁、无插件依赖、兼容性好(支持 WP 5.0+),是解决“模板层预查 + 编辑器中复用”场景的最佳实践之一。











