*/ /** * This walker is responsible for displaying the navigation with native bootstrap components * Cloned by the Twittem aquivalent, since there is no composer package: * https://github.com/twittem/wp-bootstrap-navwalker * */ class Bootstrap_Walker extends \Walker_Nav_Menu { /** * @inheritdoc * @since 0.6 */ public function start_lvl(&$output, $depth = 0, $args = array() ) { $indent = str_repeat( "\t", $depth ); $output .= "\n$indent
\n"; } public function end_lvl(&$output, $depth = 0, $args = array() ) { $indent = str_repeat("\t", $depth ); $output .= "\n$indent
\n"; } /** * This method uses the Wordpress "the_title" and "walker_nav_menu_start_el" hooks. * * @param string $output * @param \WP_Post $item * @param int $depth * @param \stdClass|array $args * @param int $id */ public function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) { if($depth === 0) { $item_output = $this->build_item($item, $depth, $args, $id); } else { $item_output = $this->build_link($item, $depth, $args); } $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args); } /** * Ends the element output, if needed. * * @since 3.0.0 * * @see Walker::end_el() * * @param string $output Passed by reference. Used to append additional content. * @param WP_Post $item Page data object. Not used. * @param int $depth Depth of page. Not Used. * @param stdClass $args An object of wp_nav_menu() arguments. */ public function end_el( &$output, $item, $depth = 0, $args = array() ) { if ( isset( $args->item_spacing ) && 'discard' === $args->item_spacing ) { $t = ''; $n = ''; } else { $t = "\t"; $n = "\n"; } if($depth == 0) { $output .= "{$n}"; } else { $output .= "{$n}"; } } /** * @inheritdoc * @since 0.6 */ 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 ); } /** * @inheritdoc * @since 0.6 */ 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 .= 'Add a menu'; $fb_output .= ''; if ( $container ) $fb_output .= ''; echo $fb_output; }*/ } /** * Build the parent item. * * @param \WP_Post $item * @param int $depth * @param \stdClass|array $args * @param int $id * @return string */ private function build_item($item, $depth, $args, $id) { $class = $this->build_item_class_attr($item, $args); $id = $this->build_item_id_attr($item, $args); $item_output = sprintf('
  • ', $id, $class); $item_output .= $this->build_link($item, $depth, $args); return $item_output; } /** * Build the dropdown items for a parent item. * * @param \WP_Post $item * @param int $depth * @param \stdClass|array $args * @return string */ private function build_link($item, $depth, $args) { $indent = str_repeat("\t", $depth); $link_attrs = $this->build_link_attrs($item, $depth, $args); $link_attrs = sprintf('%s', $args->before, $link_attrs); $item_output = $link_attrs; $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after; $item_output .= $depth === 0 ? '' : ''; $item_output .= $args->after; return $item_output; } /** * Build the filtered and escaped id attribute for the item. * This method uses the Wordpress "nav_menu_item_id" hook. * * @param \WP_Post $item * @param \stdClass|array $args * @return string */ private function build_item_id_attr($item, $args) { $id = apply_filters('nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args); $id = !empty($id) ? sprintf('id="%s"', esc_attr($id)) : ''; return $id; } /** * Build the filtered and escaped class attribute for the item. * This method uses the Wordpress "nav_menu_css_class" hook. * * @param \WP_Post $item * @param \stdClass|array $args * @return string */ private function build_item_class_attr($item, $args) { $classes = !empty($item->classes) ? (array) $item->classes : array(); $classes[] = 'nav-item'; $classes[] = sprintf('nav-item-%s', $item->ID); if ($args->has_children) { $classes[] = 'dropdown'; } if(in_array('current-menu-item', $classes)) { $classes[] = 'active'; } $classes = apply_filters('nav_menu_css_class', array_filter($classes), $item, $args); $class = join(' ', $classes); $class = !empty($class) ? sprintf('class="%s"', esc_attr($class)) : ''; return $class; } /** * Build the filtered and escaped attributes for link in the item. * This method uses the Wordpress "nav_menu_link_attributes" hook. * * @param \WP_Post$item * @param int $depth * @param \stdClass|array$args * @return string */ private function build_link_attrs($item, $depth, $args) { $attrs = array(); $attrs['title'] = !empty($item->title) ? $item->title : ''; $attrs['target'] = !empty($item->target) ? $item->target : ''; $attrs['rel'] = !empty($item->xfn) ? $item->xfn : ''; // If item has_children add atts to a. if ( $args->has_children && $depth === 0 ) { $attrs['href'] = '#'; $attrs['data-toggle'] = 'dropdown'; $attrs['class'] = 'nav-link dropdown-toggle'; $attrs['aria-haspopup'] = 'true'; $attrs['aria-expanded'] = 'false'; $attrs['id'] = 'navbarDropdownMenuLink'; } elseif($depth === 1) { $attrs['href'] = ! empty( $item->url ) ? $item->url : ''; $attrs['class'] = 'dropdown-item'; } else { $attrs['href'] = ! empty( $item->url ) ? $item->url : ''; $attrs['class'] = 'nav-link'; } $attrs = apply_filters( 'nav_menu_link_attributes', $attrs, $item, $args ); $attributes = ''; foreach ( $attrs as $attr => $value ) { if ( ! empty( $value ) ) { $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value ); $attributes .= ' ' . $attr . '="' . $value . '"'; } } return $attributes; } }