我查看了walk method from the original Walker class source at WordPress 然后用它来得到我的结果。我还添加了一些内容,包括:
添加first
和last
每节课ul
在导航菜单中添加odd
和even
课程到每个li
相对于其所在位置ul
.添加before-parent
和after-parent
课程到每个li
位于父元素之前或之后,即使元素本身是父元素以下是代码(只需将此添加到walker类中):
/**
* Traverse elements to create list from elements.
*
* Display one element if the element doesn\'t have any children otherwise,
* display the element and its children. Will only traverse up to the max
* depth and no ignore elements under that depth. It is possible to set the
* max depth to include all depths, see walk() method.
*/
public function display_element($element, &$children_elements, $max_depth, $depth = 0, $args, &$output) {
$element->is_subitem = ((!empty($children_elements[$element->ID]) && (($depth + 1) < $max_depth || ($max_depth === 0))));
if ($element->is_subitem) {
foreach ($children_elements[$element->ID] as $child) {
if ($child->current_item_parent || $this->url_compare($this->archive, $child->url)) {
$element->classes[] = \'active\';
}
}
}
$element->is_active = (!empty($element->url) && strpos($this->archive, $element->url));
if ($element->is_active) {
$element->classes[] = \'active\';
}
parent::display_element($element, $children_elements, $max_depth, $depth, $args, $output);
}
/*
* Display array of elements hierarchically.
* Does not assume any existing order of elements.
* $max_depth = -1 means flatly display every element.
* $max_depth = 0 means display all levels.
* $max_depth > 0 specifies the number of display levels.
*/
public function walk( $elements, $max_depth ) {
$args = array_slice( func_get_args(), 2 );
$output = \'\';
// Invalid parameter or nothing to walk.
if ( $max_depth < -1 || empty( $elements ) ) {
return $output;
}
$parent_field = $this->db_fields[\'parent\'];
// Flat display.
if ( -1 == $max_depth ) {
$empty_array = array();
foreach ( $elements as $e )
$this->display_element( $e, $empty_array, 1, 0, $args, $output );
return $output;
}
/*
* Need to display in hierarchical order.
* Separate elements into two buckets: top level and children elements.
* Children_elements is two dimensional array, eg.
* Children_elements[10][] contains all sub-elements whose parent is 10.
*/
$top_level_elements = array();
$children_elements = array();
foreach ( $elements as $e ) {
if ( empty( $e->$parent_field ) )
$top_level_elements[] = $e;
else
$children_elements[ $e->$parent_field ][] = $e;
}
/*
* When none of the elements is top level.
* Assume the first one must be root of the sub elements.
*/
if ( empty( $top_level_elements ) ) {
$first = array_slice( $elements, 0, 1 );
$root = $first[0];
$top_level_elements = array();
$children_elements = array();
foreach ( $elements as $e ) {
if ( $root->$parent_field == $e->$parent_field )
$top_level_elements[] = $e;
else
$children_elements[ $e->$parent_field ][] = $e;
}
}
/*
* Add number of positions per hierarchy using arrays from earlier at the top of the function.
* One for top level elements and the other for child elements.
*/
foreach ( $top_level_elements as $i => $e ) { // Loop to add classes to top level elements loop.
array_push( $e->classes, ( $i+1 ) % 2 ? \'odd\' : \'even\' ); // Add odd and even classes based on position.
// Add [before | after]-parent classes to element.
if ($i <> count( $top_level_elements ) - 1 ) { // If it is not the last element.
if (array_key_exists($top_level_elements[$i + 1 ]->ID, $children_elements)) { // If next element is a parent.
array_push($e->classes, \'before-parent\'); // Add before-parent class.
}
}
if ($i <> 0) { // If it is not the first element.
if (array_key_exists($top_level_elements[$i - 1 ]->ID, $children_elements)) { // If previous element is a parent.
array_push($e->classes, \'after-parent\'); // Add after-parent class.
}
}
// Add first and last classes to items.
if ( $i == 0 ) {
array_push( $e->classes, \'first\' ); // Add first class to first item.
} elseif ( $i == ( count( $top_level_elements ) - 1 ) ) {
array_push( $e->classes, \'last\' ); // Add last class to last item.
}
}
foreach ( $children_elements as $children ) { // Loop to add classes to child level elements loop.
foreach ( $children as $i => $e ) {
array_push( $e->classes, ( $i+1 ) % 2 ? \'odd\' : \'even\' ); // Add odd and even classes based on position.
// Add [before | after]-parent classes to element.
if ($i <> count( $children ) - 1 ) { // If it is not the last element.
if (array_key_exists($children[$i + 1 ]->ID, $children_elements)) { // If next element is a parent.
array_push($e->classes, \'before-parent\'); // Add before-parent class.
}
}
if ($i <> 0) { // If it is not the first element.
if (array_key_exists($children[$i - 1 ]->ID, $children_elements)) { // If previous element is a parent.
array_push($e->classes, \'after-parent\'); // Add after-parent class.
}
}
if ( $i == 0 ) {
array_push( $e->classes, \'first\' ); // Add first class to first item.
}if ( $i == ( count( $children ) - 1 ) ) {
array_push( $e->classes, \'last\' ); // Add last class to last item.
}
}
}
foreach ( $top_level_elements as $e )
$this->display_element( $e, $children_elements, $max_depth, 0, $args, $output );
/*
* If we are displaying all levels, and remaining children_elements is not empty,
* then we got orphans, which should be displayed regardless.
*/
if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) {
$empty_array = array();
foreach ( $children_elements as $orphans )
foreach ( $orphans as $op )
$this->display_element( $op, $empty_array, 1, 0, $args, $output );
}
return $output;
}
我还分享了我的整个
detailed navigational menu walker 如果您希望使用它,请访问Github。