WordPress输出Bootstrap导航栏结构的菜单

文章目录

最近tennfy在用Bootstrap重写博客主题,由于之前没有用过Bootstrap,所以也是花了不少功夫来了解Bootstrap。Bootstrap提供了很完整的css样式布局,对于有一定前端基础的人来说真的非常方便。

利用Bootstrap做wordpress主题遇到的第一个问题就是输出Bootstrap导航栏结构的菜单,这样才能够利用Bootstrap提供的样式进行菜单的显示。本文就来介绍下如何实现wordpress输出Bootstrap的菜单结构。

Bootstrap导航栏结构

常见的Bootstrap导航栏为如下形式:

defaultnavbar_demo

其HTML结构为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<nav class="navbar navbar-default" role="navigation">
   <div class="navbar-header">
      <a class="navbar-brand" href="#">W3Cschool</a>
   </div>
   <div>
      <ul class="nav navbar-nav">
         <li class="active"><a href="#">iOS</a></li>
         <li><a href="#">SVN</a></li>
         <li class="dropdown">
            <a href="#" class="dropdown-toggle" data-toggle="dropdown">
               Java 
               <b class="caret"></b>
            </a>
            <ul class="dropdown-menu">
               <li><a href="#">jmeter</a></li>
               <li><a href="#">EJB</a></li>
               <li><a href="#">Jasper Report</a></li>
               <li class="divider"></li>
               <li><a href="#">分离的链接</a></li>
               <li class="divider"></li>
               <li><a href="#">另一个分离的链接</a></li>
            </ul>
         </li>
      </ul>
   </div>
</nav>

自定义wp_nav_menu函数

熟悉wordpress的朋友都知道,wordpress一般采用wp_nav_menu函数输出菜单,而通过该函数输出的菜单是得不到上述的html结构的。不过值得高兴的是,wp_nav_menu函数支持自定义输出html结构。

wordpress中wp_nav_menu函数的参数如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php   
 
$defaults = array(   
    'theme_location'  => '',   
    'menu'            => '',   
    'container'       => 'div',   
    'container_class' => '',   
    'container_id'    => '',   
    'menu_class'      => 'menu',   
    'menu_id'         => '',   
    'echo'            => true,   
    'fallback_cb'     => 'wp_page_menu',   
    'before'          => '',   
    'after'           => '',   
    'link_before'     => '',   
    'link_after'      => '',   
    'items_wrap'      => '<ul id="%1$s" class="%2$s">%3$s</ul>',   
    'depth'           => 0,   
    'walker'          => ''  
);   
 
wp_nav_menu( $defaults );   
 
?>

其中,我们需要修改的就是walker参数。

输出Bootstrap导航栏结构菜单

在header.php中,通过如下代码输出导航栏菜单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<nav class="navbar navbar-default" role="navigation">
   <div class="navbar-header">
      <a class="navbar-brand" href="#">TENNFY WU</a>
   </div>
   <div>
       <?php   
	    wp_nav_menu( array(  
		'theme_location' => 'cat_nav',  
		'depth' => 2,   
		'container' => false,   
	        'menu_class' => 'nav navbar-nav',   
		'fallback_cb' => 'wp_page_menu',   
		//添加或更改walker参数   
		'walker' => new wp_bootstrap_navwalker())   
	     );   
	?>
   </div>
</nav>

上面代码中walker参数的值是一个类,所以接下来你需要添加这个类,在主题的functions.php文件中添加下面代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
<?php   
 
/**
 * Class Name: wp_bootstrap_navwalker  
 * GitHub URI: https://github.com/twittem/wp-bootstrap-navwalker  
 * Description: A custom WordPress nav walker class to implement the Bootstrap 3 navigation style in a custom theme using the WordPress built in menu manager.  
 * Version: 2.0.4  
 * Author: Edward McIntyre - @twittem  
 * License: GPL-2.0+  
 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt  
 */  
 
class wp_bootstrap_navwalker extends Walker_Nav_Menu {   
 
    /**
     * @see Walker::start_lvl()  
     * @since 3.0.0  
     *  
     * @param string $output Passed by reference. Used to append additional content.  
     * @param int $depth Depth of page. Used for padding.  
     */  
    public function start_lvl( &$output, $depth = 0, $args = array() ) {   
        $indent = str_repeat( "\t", $depth );   
        $output .= "\n$indent<ul role=\"menu\" class=\" dropdown-menu\">\n";   
    }   
 
    /**
     * @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 int $current_page Menu item ID.  
     * @param object $args  
     */  
    public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {   
        $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';   
 
        /**
         * Dividers, Headers or Disabled  
         * =============================  
         * Determine whether the item is a Divider, Header, Disabled or regular  
         * menu item. To prevent errors we use the strcasecmp() function to so a  
         * comparison that is not case sensitive. The strcasecmp() function returns  
         * a 0 if the strings are equal.  
         */  
        if ( strcasecmp( $item->attr_title, 'divider' ) == 0 && $depth === 1 ) {   
            $output .= $indent . '<li role="presentation" class="divider">';   
        } else if ( strcasecmp( $item->title, 'divider') == 0 && $depth === 1 ) {   
            $output .= $indent . '<li role="presentation" class="divider">';   
        } else if ( strcasecmp( $item->attr_title, 'dropdown-header') == 0 && $depth === 1 ) {   
            $output .= $indent . '<li role="presentation" class="dropdown-header">' . esc_attr( $item->title );   
        } else if ( strcasecmp($item->attr_title, 'disabled' ) == 0 ) {   
            $output .= $indent . '<li role="presentation" class="disabled"><a href="#">' . esc_attr( $item->title ) . '</a>';   
        } else {   
 
            $class_names = $value = '';   
 
            $classes = empty( $item->classes ) ? array() : (array) $item->classes;   
            $classes[] = 'menu-item-' . $item->ID;   
 
            $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );   
 
            if ( $args->has_children )   
                $class_names .= ' dropdown';   
 
            if ( in_array( 'current-menu-item', $classes ) )   
                $class_names .= ' active';   
 
            $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';   
 
            $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );   
            $id = $id ? ' id="' . esc_attr( $id ) . '"' : '';   
 
            $output .= $indent . '<li' . $id . $value . $class_names .'>';   
 
            $atts = array();   
            $atts['title']  = ! empty( $item->title )   ? $item->title  : '';   
            $atts['target'] = ! empty( $item->target )  ? $item->target : '';   
            $atts['rel']    = ! empty( $item->xfn )     ? $item->xfn    : '';   
 
            // If item has_children add atts to a.   
            if ( $args->has_children && $depth === 0 ) {   
                $atts['href']           = '#';   
                $atts['data-toggle']    = 'dropdown';   
                $atts['class']          = 'dropdown-toggle';   
                $atts['aria-haspopup']  = 'true';   
            } else {   
                $atts['href'] = ! empty( $item->url ) ? $item->url : '';   
            }   
 
            $atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args );   
 
            $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;   
 
            /*
             * Glyphicons  
             * ===========  
             * Since the the menu item is NOT a Divider or Header we check the see  
             * if there is a value in the attr_title property. If the attr_title  
             * property is NOT null we apply it as the class name for the glyphicon.  
             */  
            if ( ! empty( $item->attr_title ) )   
                $item_output .= '<a'. $attributes .'><span class="glyphicon ' . esc_attr( $item->attr_title ) . '"></span>&nbsp;';   
            else  
                $item_output .= '<a'. $attributes .'>';   
 
            $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;   
            $item_output .= ( $args->has_children && 0 === $depth ) ? ' <span class="caret"></span></a>' : '</a>';   
            $item_output .= $args->after;   
 
            $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );   
        }   
    }   
 
    /**
     * 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.  
     *  
     * This method shouldn't be called directly, use the walk() method instead.  
     *  
     * @see Walker::start_el()  
     * @since 2.5.0  
     *  
     * @param object $element Data object  
     * @param array $children_elements List of elements to continue traversing.  
     * @param int $max_depth Max depth to traverse.  
     * @param int $depth Depth of current element.  
     * @param array $args  
     * @param string $output Passed by reference. Used to append additional content.  
     * @return null Null on failure with no changes to parameters.  
     */  
    public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {   
        if ( ! $element )   
            return;   
 
        $id_field = $this->db_fields['id'];   
 
        // Display this element.   
        if ( is_object( $args[0] ) )   
           $args[0]->has_children = ! empty( $children_elements[ $element->$id_field ] );   
 
        parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );   
    }   
 
    /**
     * Menu Fallback  
     * =============  
     * If this function is assigned to the wp_nav_menu's fallback_cb variable  
     * and a manu has not been assigned to the theme location in the WordPress  
     * menu manager the function with display nothing to a non-logged in user,  
     * and will add a link to the WordPress menu manager if logged in as an admin.  
     *  
     * @param array $args passed from the wp_nav_menu function.  
     *  
     */  
    public static function fallback( $args ) {   
        if ( current_user_can( 'manage_options' ) ) {   
 
            extract( $args );   
 
            $fb_output = null;   
 
            if ( $container ) {   
                $fb_output = '<' . $container;   
 
                if ( $container_id )   
                    $fb_output .= ' id="' . $container_id . '"';   
 
                if ( $container_class )   
                    $fb_output .= ' class="' . $container_class . '"';   
 
                $fb_output .= '>';   
            }   
 
            $fb_output .= '<ul';   
 
            if ( $menu_id )   
                $fb_output .= ' id="' . $menu_id . '"';   
 
            if ( $menu_class )   
                $fb_output .= ' class="' . $menu_class . '"';   
 
            $fb_output .= '>';   
            $fb_output .= '<li><a href="' . admin_url( 'nav-menus.php' ) . '">Add a menu</a></li>';   
            $fb_output .= '</ul>';   
 
            if ( $container )   
                $fb_output .= '</' . $container . '>';   
 
            echo $fb_output;   
        }   
    }   
}


本文出自 TENNFY WU,转载时请注明出处及相应链接。

本文永久链接: http://www.tennfy.com/4097.html

下一篇文章:

上一篇文章:

3人参与了讨论

  1. 凯凯 说:

    请问博主,这个方法可以在去除ul,li标签之后把选择器添加给a标签嘛?希望博主能回复~ 谢谢~

  2. leejon 说:

    博主的博客侧边栏热点+随机也是Bootstrap导航做的吗? :?:

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

2 + 7 = ?


您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

返回顶部