Kikito的上面的答案可以完成操作,但不够灵活。我认为更好的方法是这样的:
function display_element($element, &$children_elements, $max_depth, $depth=0, $args, &$output) {
// the first few lines of the method...
//display this element; handle either arrays or objects gracefully
if ( is_array( $args[0] ) )
$args[0]['has_children'] = ! empty( $children_elements[$element->$id_field] );
elseif ( is_object($args[0]) )
$args[0]->has_children = ! empty( $children_elements[$element->$id_field] );
// the rest of the method...
}
覆盖
Walker::display_element()
是正确的做法,但最好实际解决问题而不是仅仅在此处添加一个类,原因有两个。首先,真正的问题不是缺少类,而是WordPress中未修补的错误,正如Kikito所指出的:问题在于
$args[0]
并不总是一个数组。这似乎是
Walker::display_element()
通常期望的类型,但我们实际上在处理
Walker_Nav_Menu::display_element()
,在这种情况下,
args
以标准对象类型而不是数组类型传递。因此,我们只需要使用对象符号而不是数组符号添加
has_children
元素即可。问题解决了![1]
添加那个
elseif
可以处理普通导航菜单的情况。这与希望进入核心类的
此补丁相同,到那时,您将不再需要扩展它。他们可能会进一步修补程序以解决
$args[0]
既不是数组也不是对象的情况,但我不认为会发生这种情况。
其次,为了保持各种方法和类之间的良好分离,应该在
start_el()
方法或其他地方添加类,因为
display_element()
并没有处理任何类的操作。
因此,您可以随意覆盖
start_el()
:您可以添加自己的自定义类,或者完全忽略元素,或者提供自定义文本,或者任何您喜欢的内容。(在我的情况下,我正在解决一个现有的Javascript菜单实现,它基于父项和子项具有非常特定的类要求,因此我不能仅将相同的类添加到每个具有子项的元素中 - 这正是为什么这种关注点分离很重要的原因。)在我的代码中:
function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) {
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
$class_names = $value = '';
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
$classes[] = 'menu-item-' . $item->ID;
$has_children = (is_object($args) && $args->has_children) || (is_array($args) && $args['has_children']);
if ($has_children) {
}
}
[1] 当然,这是像PHP这样的动态类型语言可能存在的潜在陷阱之一...只要你小心,这不是问题。WordPress开发人员在这里没有小心。
wp-admin
中分配了菜单?我在干净的安装中使用了twentyeleven
和没有其他插件进行了测试。 - janw