如何在Divi博客模块中按ACF字段筛选CPT实现显示/隐藏
解决Divi博客模块筛选ACF True/False字段自定义文章类型的问题
问题场景
在Divi主题环境下,通过ACF插件给自定义文章类型(CPT)添加了名为show的True/False字段,希望仅展示该字段值为True的CPT内容,但Divi博客模块的高级条件中无对应筛选选项,此前使用pre_get_posts钩子的代码未生效。
失效原因分析
之前的代码无法生效,核心原因是Divi博客模块使用的是自定义WP_Query查询,而非主查询(main query),代码里的$query->is_main_query()判断会直接跳过模块的查询请求,导致筛选规则未被应用。
可行解决方案
方案1:使用Divi专属钩子(推荐)
Divi提供了et_pb_blog_query_args钩子,专门用于修改博客模块的查询参数,精准且不会影响其他查询逻辑。将以下代码添加到子主题的functions.php文件中:
function filter_divi_blog_cpt_by_acf_show_field( $query_args, $instance ) { // 仅在前端生效,且匹配目标自定义文章类型(替换为你的CPT slug) if ( !is_admin() && isset( $query_args['post_type'] ) && $query_args['post_type'] === 'new_CPT' ) { // 追加ACF字段的筛选条件 $query_args['meta_query'][] = array( 'key' => 'show', 'value' => 1, // ACF True/False字段选中时存储的值为1 'compare' => '=', ); } return $query_args; } add_filter( 'et_pb_blog_query_args', 'filter_divi_blog_cpt_by_acf_show_field', 10, 2 );
注意:将代码中的
new_CPT替换为你实际注册的自定义文章类型的slug。
方案2:调整pre_get_posts的判断逻辑
如果需要全局过滤该CPT的所有前端查询(包括博客模块和其他列表页面),可以修改原有代码,移除is_main_query()的限制,同时避免覆盖已有查询条件:
function filter_CPT_by_custom_field( $query ) { // 排除后台查询,且匹配目标CPT if ( !is_admin() && $query->get( 'post_type' ) === 'new_CPT' ) { // 获取现有meta_query,避免覆盖原有规则 $meta_query = $query->get( 'meta_query', array() ); $meta_query[] = array( 'key' => 'show', 'value' => 1, 'compare' => '=', ); $query->set( 'meta_query', $meta_query ); } } add_action( 'pre_get_posts', 'filter_CPT_by_custom_field' );
额外注意事项
- 确认ACF字段的键为
show,无拼写错误(可在ACF字段编辑页面的「字段设置」中查看); - ACF的True/False字段,选中时数据库存储值为
1,未选中为0,代码中value设为1符合逻辑; - 修改代码后,清除WordPress及Divi的缓存(若开启),避免缓存导致修改不生效。
内容的提问来源于stack exchange,提问作者GZargi
相关产品推荐
相关产品推荐

