自定义NAV_WAKER中有子项(_W)

时间:2015-08-17 作者:Dawid Adach

我正在尝试创建自定义菜单导航行者。我添加了以下代码

function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output )
{
    $id_field = $this->db_fields[\'id\'];
    if ( is_object( $args[0] ) ) {
        $args[0]->has_children = ! empty( $children_elements[$element->$id_field] );
    }
    return parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
}
因此,我可以在start\\u el函数中使用if($args->has\\u children)语句,不幸的是,在end\\u el函数中似乎没有相同的代码。

完整代码:

class CSS_Menu_Walker2 extends Walker {
  /**
   * What the class handles.
   *
   * @see Walker::$tree_type
   * @since 3.0.0
   * @var string
   */
  public $tree_type = array( \'post_type\', \'taxonomy\', \'custom\' );

  /**
   * Database fields to use.
   *
   * @see Walker::$db_fields
   * @since 3.0.0
   * @todo Decouple this.
   * @var array
   */
  public $db_fields = array( \'parent\' => \'menu_item_parent\', \'id\' => \'db_id\' );

  /**
   * Starts the list before the elements are added.
   *
   * @see Walker::start_lvl()
   *
   * @since 3.0.0
   *
   * @param string $output Passed by reference. Used to append additional content.
   * @param int    $depth  Depth of menu item. Used for padding.
   * @param array  $args   An array of arguments. @see wp_nav_menu()
   */
  public function start_lvl( &$output, $depth = 0, $args = array() ) {
    $indent = str_repeat("\\t", $depth);
    $output .= "\\n$indent <div class=\\"collapsible-body\\"> <ul class=\\"sub-menu\\">\\n";
  }

  /**
   * Ends the list of after the elements are added.
   *
   * @see Walker::end_lvl()
   *
   * @since 3.0.0
   *
   * @param string $output Passed by reference. Used to append additional content.
   * @param int    $depth  Depth of menu item. Used for padding.
   * @param array  $args   An array of arguments. @see wp_nav_menu()
   */
  public function end_lvl( &$output, $depth = 0, $args = array() ) {
    $indent = str_repeat("\\t", $depth);

    $output .= "$indent</ul></div>\\n";
  }

  /**
   * Start the element output.
   *
   * @see Walker::start_el()
   *
   * @since 3.0.0
   *
   * @param string $output Passed by reference. Used to append additional content.
   * @param object $item   Menu item data object.
   * @param int    $depth  Depth of menu item. Used for padding.
   * @param array  $args   An array of arguments. @see wp_nav_menu()
   * @param int    $id     Current item ID.
   */


    function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output )
    {
        $id_field = $this->db_fields[\'id\'];
        if ( is_object( $args[0] ) ) {
            $args[0]->has_children = ! empty( $children_elements[$element->$id_field] );
        }
        return parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
    }



  public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {


    $indent = ( $depth ) ? str_repeat( "\\t", $depth ) : \'\';

    $classes = empty( $item->classes ) ? array() : (array) $item->classes;
    $classes[] = \'menu-item-\' . $item->ID;

    /**
     * Filter the CSS class(es) applied to a menu item\'s list item element.
     *
     * @since 3.0.0
     * @since 4.1.0 The `$depth` parameter was added.
     *
     * @param array  $classes The CSS classes that are applied to the menu item\'s `<li>` element.
     * @param object $item    The current menu item.
     * @param array  $args    An array of {@see wp_nav_menu()} arguments.
     * @param int    $depth   Depth of menu item. Used for padding.
     */
    $class_names = join( \' \', apply_filters( \'nav_menu_css_class\', array_filter( $classes ), $item, $args, $depth ) );
    $class_names = $class_names ? \' class="\' . esc_attr( $class_names ) . \'"\' : \'\';

    /**
     * Filter the ID applied to a menu item\'s list item element.
     *
     * @since 3.0.1
     * @since 4.1.0 The `$depth` parameter was added.
     *
     * @param string $menu_id The ID that is applied to the menu item\'s `<li>` element.
     * @param object $item    The current menu item.
     * @param array  $args    An array of {@see wp_nav_menu()} arguments.
     * @param int    $depth   Depth of menu item. Used for padding.
     */
    $id = apply_filters( \'nav_menu_item_id\', \'menu-item-\'. $item->ID, $item, $args, $depth );
    $id = $id ? \' id="\' . esc_attr( $id ) . \'"\' : \'\';

    if ( $args->has_children ) {
    $output .= $indent .  \'<ul class="collapsible collapsible-accordion">\';
    $output .= $indent . \'<a class="collapsible-header  waves-effect waves-teal ">\';
    }
    $output .= $indent . \'<li\' . $id . $class_names .\'>\';

    $atts = array();
    $atts[\'title\']  = ! empty( $item->attr_title ) ? $item->attr_title : \'\';
    $atts[\'target\'] = ! empty( $item->target )     ? $item->target     : \'\';
    $atts[\'rel\']    = ! empty( $item->xfn )        ? $item->xfn        : \'\';
    $atts[\'href\']   = ! empty( $item->url )        ? $item->url        : \'\';

    /**
     * Filter the HTML attributes applied to a menu item\'s anchor element.
     *
     * @since 3.6.0
     * @since 4.1.0 The `$depth` parameter was added.
     *
     * @param array $atts {
     *     The HTML attributes applied to the menu item\'s `<a>` element, empty strings are ignored.
     *
     *     @type string $title  Title attribute.
     *     @type string $target Target attribute.
     *     @type string $rel    The rel attribute.
     *     @type string $href   The href attribute.
     * }
     * @param object $item  The current menu item.
     * @param array  $args  An array of {@see wp_nav_menu()} arguments.
     * @param int    $depth Depth of menu item. Used for padding.
     */
    $atts = apply_filters( \'nav_menu_link_attributes\', $atts, $item, $args, $depth );

    $attributes = \'\';
    foreach ( $atts as $attr => $value ) {
      if ( ! empty( $value ) ) {
        $value = ( \'href\' === $attr ) ? esc_url( $value ) : esc_attr( $value );
        $attributes .= \' \' . $attr . \'="\' . $value . \'"\';
      }
    }

    $item_output = $args->before;
    if (!$args->has_children ) 
    $item_output .= \'<a\'. $attributes .\'>\';
    /** This filter is documented in wp-includes/post-template.php */
    $item_output .= $args->link_before . apply_filters( \'the_title\', $item->title, $item->ID ) . $args->link_after;
    if (!$args->has_children ) 
    $item_output .= \'</a>\';
    $item_output .= $args->after;



    /**
     * Filter a menu item\'s starting output.
     *
     * The menu item\'s starting output only includes `$args->before`, the opening `<a>`,
     * the menu item\'s title, the closing `</a>`, and `$args->after`. Currently, there is
     * no filter for modifying the opening and closing `<li>` for a menu item.
     *
     * @since 3.0.0
     *
     * @param string $item_output The menu item\'s starting HTML output.
     * @param object $item        Menu item data object.
     * @param int    $depth       Depth of menu item. Used for padding.
     * @param array  $args        An array of {@see wp_nav_menu()} arguments.
     */
    $output .= apply_filters( \'walker_nav_menu_start_el\', $item_output, $item, $depth, $args );

  }

  /**
   * Ends the element output, if needed.
   *
   * @see Walker::end_el()
   *
   * @since 3.0.0
   *
   * @param string $output Passed by reference. Used to append additional content.
   * @param object $item   Page data object. Not used.
   * @param int    $depth  Depth of page. Not Used.
   * @param array  $args   An array of arguments. @see wp_nav_menu()
   */
  public function end_el( &$output, $item, $depth = 0, $args = array() ) {

    $output .= "</li>\\n";

  }

} // Walker_Nav_Menu
?>
a
我做错什么了吗?

2 个回复
最合适的回答,由SO网友:Jorge Raigoza 整理而成

我也有同样的问题。一些答案声称您可以使用$args->has_children$args[0]->has_children, 但它从未添加到$args中。有时has_children 添加在下面$args->walker->has_children, 但它总是设置为false, 换句话说,没用。。。

作为一种解决方法,我使用的当前模板向包含子项的项添加了一个类(菜单项有子项),因此我在$item->classes.

function end_el( &$output, $item, $depth = 0, $args = array() ) {

    if( !empty($item->classes) && 
        is_array($item->classes) && 
        in_array(\'menu-item-has-children\', $item->classes) ){

        // This guy has children

    }
}
我想,您可以在start\\u el函数中添加一个标记,然后搜索它。。。

我希望这有帮助。如果你有更好的解决方案,请分享。

SO网友:Jefferson

这是一条检查$children_elements 因为$element->ID 作为顶级数组键,因此是父级。

$is_parent = array_key_exists( $element->ID, $children_elements );
EDIT: 我应该提到这个必须用在Walker 方法display_element 因此,要使用该方法,您需要将该方法添加到自定义walker类中,如下所示:

class Your_Custom_Walker extends Walker_Nav_Menu {

    public function display_element( $element, &$children_elements, $max_depth, $depth = 0, $args, &$output ) {

        $is_parent = array_key_exists( $element->ID, $children_elements );

        //do stuff with $is_parent

    }
}
如果您尚未使用display_element 方法,然后这个“一行”开始看起来更麻烦。此方法使遍历和操作菜单树变得更容易,因为它在传递给之前发生start_el 并允许您访问$children_elements.

结束

相关推荐

如何向导航栏添加schema.org SiteNavigationElement和属性URL?

我想添加架构。组织机构SiteNavigationElement 以及导航栏链接的相对url属性。我有以下几点:<nav class=\"navbar navbar-default navbar-fixed-top\" id=\"menu-nav\" role=\"navigation\"> <!-- Brand and toggle get grouped for better mobile display --> <div class=\"navb