-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathwp_bem_menu.php
159 lines (116 loc) · 6.23 KB
/
wp_bem_menu.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
<?php
/**
* Walker Texas Ranger
* Inserts some BEM naming sensibility into Wordpress menus
*/
class walker_texas_ranger extends Walker_Nav_Menu {
function __construct($css_class_prefix) {
$this->css_class_prefix = $css_class_prefix;
// Define menu item names appropriately
$this->item_css_class_suffixes = array(
'item' => '__item',
'parent_item' => '__item--parent',
'active_item' => '__item--active',
'parent_of_active_item' => '__item--parent--active',
'ancestor_of_active_item' => '__item--ancestor--active',
'sub_menu' => '__sub-menu',
'sub_menu_item' => '__sub-menu__item',
'link' => '__link',
);
}
// Check for children
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 );
}
function start_lvl(&$output, $depth = 1, $args=array()) {
$real_depth = $depth + 1;
$indent = str_repeat("\t", $real_depth);
$prefix = $this->css_class_prefix;
$suffix = $this->item_css_class_suffixes;
$classes = array(
$prefix . $suffix['sub_menu'],
$prefix . $suffix['sub_menu']. '--' . $real_depth
);
$class_names = implode( ' ', $classes );
// Add a ul wrapper to sub nav
$output .= "\n" . $indent . '<ul class="'. $class_names .'">' ."\n";
}
// Add main/sub classes to li's and links
function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
global $wp_query;
$indent = ( $depth > 0 ? str_repeat( " ", $depth ) : '' ); // code indent
$prefix = $this->css_class_prefix;
$suffix = $this->item_css_class_suffixes;
// Item classes
$item_classes = array(
'item_class' => $depth == 0 ? $prefix . $suffix['item'] : '',
'parent_class' => $args->has_children ? $parent_class = $prefix . $suffix['parent_item'] : '',
'active_page_class' => in_array("current-menu-item",$item->classes) ? $prefix . $suffix['active_item'] : '',
'active_parent_class' => in_array("current-menu-parent",$item->classes) ? $prefix . $suffix['parent_of_active_item'] : '',
'active_ancestor_class' => in_array("current-menu-ancestor",$item->classes) ? $prefix . $suffix['ancestor_of_active_item'] : '',
'depth_class' => $depth >=1 ? $prefix . $suffix['sub_menu_item'] . ' ' . $prefix . $suffix['sub_menu'] . '--' . $depth . '__item' : '',
'item_id_class' => $prefix . '__item--'. $item->object_id,
'user_class' => $item->classes[0] !== '' ? $prefix . '__item--'. $item->classes[0] : ''
);
// convert array to string excluding any empty values
$class_string = implode(" ", array_filter($item_classes));
// Add the classes to the wrapping <li>
$output .= $indent . '<li class="' . $class_string . '">';
// Link classes
$link_classes = array(
'item_link' => $depth == 0 ? $prefix . $suffix['link'] : '',
'depth_class' => $depth >=1 ? $prefix . $suffix['sub_menu'] . $suffix['link'] . ' ' . $prefix . $suffix['sub_menu'] . '--' . $depth . $suffix['link'] : '',
);
$link_class_string = implode(" ", array_filter($link_classes));
$link_class_output = 'class="' . $link_class_string . '"';
// link attributes
$attributes = ! empty($item->attr_title) ? ' title="' . esc_attr($item->attr_title) .'"' : '';
$attributes .= ! empty($item->target) ? ' target="' . esc_attr($item->target ) .'"' : '';
$attributes .= ! empty($item->xfn) ? ' rel="' . esc_attr($item->xfn ) .'"' : '';
$attributes .= ! empty($item->url) ? ' href="' . esc_attr($item->url ) .'"' : '';
// Creatre link markup
$item_output = $args->before;
$item_output .= '<a' . $attributes . ' ' . $link_class_output . '>';
$item_output .= $args->link_before;
$item_output .= apply_filters('the_title', $item->title, $item->ID);
$item_output .= $args->link_after;
$item_output .= $args->after;
$item_output .= '</a>';
// Filter <li>
$output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
}
}
/**
* bem_menu returns an instance of the walker_texas_ranger class with the following arguments
* @param string $location This must be the same as what is set in wp-admin/settings/menus for menu location.
* @param string $css_class_prefix This string will prefix all of the menu's classes, BEM syntax friendly
* @param arr/string $css_class_modifiers Provide either a string or array of values to apply extra classes to the <ul> but not the <li's>
* @return [type]
*/
function bem_menu($location = "main_menu", $css_class_prefix = 'main-menu', $css_class_modifiers = null){
// Check to see if any css modifiers were supplied
if($css_class_modifiers){
if(is_array($css_class_modifiers)){
$modifiers = implode(" ", $css_class_modifiers);
} elseif (is_string($css_class_modifiers)) {
$modifiers = $css_class_modifiers;
}
} else {
$modifiers = '';
}
$args = array(
'theme_location' => $location,
'container' => false,
'items_wrap' => '<ul class="' . $css_class_prefix . ' ' . $modifiers . '">%3$s</ul>',
'walker' => new walker_texas_ranger($css_class_prefix, true)
);
if (has_nav_menu($location)){
return wp_nav_menu($args);
}else{
echo "<p>You need to first define a menu in WP-admin<p>";
}
}