WordPress子主题如何覆写父主题mega_menu_attributes方法修改data-numberposts值
解决方案
方案一:高优先级钩子覆盖(推荐)
该方案无需修改父主题逻辑、无需移除原有过滤器,兼容性最强,实现成本最低:
// 子主题functions.php中添加 function custom_modify_child_term_post_count( $atts, $item, $args, $depth ) { // 匹配child-term场景:存在data-term属性且原数值为6时替换为12 if ( isset( $atts['data-term'], $atts['data-numberposts'] ) && 6 === $atts['data-numberposts'] ) { $atts['data-numberposts'] = 12; } return $atts; } // 优先级设为11,晚于父主题的10优先级回调,在父主题赋值完成后修改 add_filter( 'nav_menu_link_attributes', 'custom_modify_child_term_post_count', 11, 4 );
方案二:正确移除父主题过滤器后替换
如果需要完全自定义整个方法逻辑,可以使用该方案,需先修复之前移除过滤器的错误:
- 首先你之前的移除代码无效,是因为
$this只能在类内部使用,你需要先找到父主题中对应 mega menu 类的实例化全局变量名(父主题代码中一般会有类似$GLOBALS['theme_mega_menu'] = new Theme_Mega_Menu();的逻辑,替换下方代码中的$GLOBALS['theme_mega_menu']为实际的实例变量) - 添加如下代码到子主题functions.php:
// 移除父主题原有过滤器 function remove_parent_mega_menu_filter() { remove_filter( 'nav_menu_link_attributes', array( $GLOBALS['theme_mega_menu'], 'mega_menu_attributes' ), 10, 4 ); } // 使用after_setup_theme钩子,保证父主题加载完成后再执行移除,优先级设为20 add_action( 'after_setup_theme', 'remove_parent_mega_menu_filter', 20 ); // 挂载自定义的mega菜单属性处理逻辑 function custom_mega_menu_attributes( $atts, $item, $args, $depth ) { // 复用父主题的判断方法,替换数值为12 $menu_type = $GLOBALS['theme_mega_menu']->is_mega_menu( $item, $args ); if ( in_array( $menu_type, array( 'term', 'child-term' ), true ) ) { $atts['data-term'] = $item->object_id; if ( 'term' === $menu_type ) { $atts['data-numberposts'] = 5; } elseif ( 'child-term' === $menu_type ) { $atts['data-numberposts'] = 12; } } if ( isset( $item->mega_menu_children ) && 'mixed' === $menu_type ) { $layout = $GLOBALS['theme_mega_menu']->identify_mega_menu_layout( $item->mega_menu_children ); if ( 'posts' === $layout ) { $posts = array(); foreach ( $item->mega_menu_children as $_post ) { $posts[] = $_post->object_id; } $atts['data-posts'] = implode( '|', $posts ); $atts['data-numberposts'] = 5; } } return $atts; } add_filter( 'nav_menu_link_attributes', 'custom_mega_menu_attributes', 10, 4 );
之前尝试失败的原因
- 移除过滤器时使用
$this无效:$this仅在类内部指代当前实例,子主题的全局函数中没有对应的类实例,导致移除操作没有命中父主题的回调 - 直接重写函数/覆盖文件不可行:父主题加载优先级高于子主题,且没有做
function_exists/class_exists判断,重复定义会触发PHP报错
内容的提问来源于stack exchange,提问作者nilssonc
相关产品推荐
相关产品推荐

