WordPress函数内调用add_filter(body_class)不生效如何解决?
问题根源
add_filter不生效的核心原因是过滤器挂载时机太晚:
WordPress的body_class钩子只会在模板调用body_class()函数生成body标签class属性时触发一次。你在模板文件中调用do_action('test_callback_add_no_hero_class')时,执行顺序已经在body_class()运行之后了,这时候再往body_class上挂载回调,钩子已经执行完毕,自然不会生效。
而把add_filter直接写在函数外部能正常运行,是因为主题的functions.php在WordPress初始化阶段就会被加载,这个阶段远早于模板输出、body_class()执行的时间点,提前挂载的过滤器回调可以被正常触发。
可行修复方案
方案1:直接挂载过滤器,在回调内做条件判断(推荐)
不需要额外自定义action中转,直接在functions.php中挂载body_class过滤器,在回调内部判断是否需要添加目标class即可:
add_filter( 'body_class', 'pxlr_nohero_custom_class' ); function pxlr_nohero_custom_class( $classes ) { // 此处替换为你原本需要触发加class逻辑的判断规则,比如判断页面类型、自定义字段值、是否满足无hero的展示条件 if ( 你的判断逻辑,例如 is_singular('product')、get_post_meta(get_the_ID(), 'hide_hero', true) 等 ) { $classes[] = 'pxlr-site-no-hero'; } return $classes; }
方案2:保留自定义action逻辑,调整触发时机
如果你一定要通过自定义action控制过滤器挂载,必须保证do_action('test_callback_add_no_hero_class')的调用位置在模板中body_class()函数执行之前,示例:
<?php // 模板最顶部先触发挂载动作,此时还未执行到body_class() do_action('test_callback_add_no_hero_class'); ?> <!DOCTYPE html> <html <?php language_attributes(); ?>> <head> <meta charset="<?php bloginfo( 'charset' ); ?>"> <?php wp_head(); ?> </head> <!-- 这里调用body_class()时,之前挂载的过滤器就能正常生效 --> <body <?php body_class(); ?>>
你原来的两种写法逻辑本身没有语法错误,只要把do_action的调用位置挪到body_class()执行之前就能正常运行。
内容的提问来源于stack exchange,提问作者PXD
相关产品推荐
相关产品推荐

