How to make custom navigation with WordPress (wp-bootstrap-nawalker) - php

I'm creating theme with WordPress and I'm using default bootstrap navbar for navigation.
<ul class="nav navbar-nav navbar-right">
<li class="active"><a class="scroll" href="#home">HOME</a></li>
<li><a class="scroll" href="#about">ABOUT</a></li>
<li><a class="scroll" href="#services">SERVICES</a></li>
<li><a class="scroll" href="#team">TEAM</a></li>
<li><a class="scroll" href="#portfolio">PORTFOLIO</a></li>
<li><a class="scroll" href="#contact">CONTACT</a></li>
</ul>
I was using wp-bootstrap-nawalker https://github.com/twittem/wp-bootstrap-navwalker for creating my navigation dynamic.
wp_nav_menu( array(
'menu' => 'primary',
'theme_location' => 'primary',
'depth' => 2,
'container' => 'div',
'container_class' => 'collapse navbar-collapse',
'container_id' => 'bs-example-navbar-collapse-1',
'menu_class' => 'nav navbar-nav navbar-right',
'fallback_cb' => 'wp_bootstrap_navwalker::fallback',
'walker' => new wp_bootstrap_navwalker()
));
Which is working fine. But I can't see scroll class inside my anchor tags. I can't see any options in wp-bootstrap-navwalker to customize my anchor tags.
The Problem: I'm having scroll class in my anchor tags. <a class="scroll"></a>. Is there any way to put scroll class inside my anchor tags.

if you want to add class inside anchor tags, you need to edit bootstrap_navwalker.php ( lines 80 -94 )
$atts = array();
$atts['title'] = ! empty( $item->title ) ? $item->title : '';
$atts['target'] = ! empty( $item->target ) ? $item->target : '';
$atts['rel'] = ! empty( $item->xfn ) ? $item->xfn : '';
$atts['class'] = 'scroll'; // class for anchor tag
// If item has_children add atts to a.
if ( $args->has_children && $depth === 0 ) {
$atts['href'] = ! empty( $item->url ) ? $item->url : '';
$atts['data-toggle'] = '';
$atts['class'] = 'scroll dropdown-toggle'; // class for dropdown anchor tag
$atts['aria-haspopup'] = 'true';
} else {
$atts['href'] = ! empty( $item->url ) ? $item->url : '';
}
wp-bootstrap-navwalker recently updated to 2.0.5, so you may want to update and the lines you need to modify may have changed.

Related

WordPress: only showing the current page’s top-level parent’s sub-menu items from a custom nav menu

I need help with combining these two codes:
this:
<?php wp_nav_menu(
array(
'theme_location' => 'primary',
'container_class' => 'collapse navbar-collapse',
'container_id' => 'navbarNavDropdown',
'menu_class' => 'navbar-nav',
'fallback_cb' => '',
'menu_id' => 'main-menu',
'walker' => new rorentrep_WP_Bootstrap_Navwalker(),
)
);
?>
and this (from https://www.minddevelopmentanddesign.com/blog/showing-current-pages-parents-sub-menu-items-custom-nav-menu-wordpress/):
<?php
$section_id = empty( $post->ancestors ) ? $post->ID : end( $post->ancestors );
$locations = get_nav_menu_locations();
$menu = wp_get_nav_menu_object( $locations[ 'primary' ] ); // 'primary' is our nav menu's name
$menu_items = wp_get_nav_menu_items( $menu->term_id, array( 'post_parent' => $section_id ) );
if( !empty( $menu_items ) ) {
echo '<ul class="section-submenu">';
foreach( $menu_items as $menu_item ) {
echo '<li>' . $menu_item->title . '</li>';
}
echo '</ul>';
}
?>
More precisely, I want the links that the second code echoes to appear as the first code.
The structure of my pages are like this:
Business
- Sub page a
- Sub page b
- Sub page c
Private
- Sub page x
- Sub page y
- Sub page z
Whenever I visit a child's page of Business I want the menu to only list Sub page a-c, and when I visit a child's page of Private I want the menu to only list Sub page x-z.
As multiple pages can be added, I do not want to target specific page id's.
The main reason for this is for the output code to wrap and nest like wp_nav_menu using walker bootstrap nav (adding current-classes to nav-items).
In your walker class, you can set the behavior for each level. Then check the depth in the element method: start_el
class Footer extends \Walker_Nav_Menu
{
function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0)
{
if ($depth == 0) {
$output .= '
<li class="list-inline-item">
<a href="' . $item->url . '" title="' . $item->title . '">
' . $item->title . '
</a>
</li>';
}
}
function start_lvl( &$output, $depth = 0, $args = array() ) {
$output.= '';
}
function end_lvl( &$output, $depth = 0, $args = array() ) {
$output.= '';
}
}

WordPress menu and bootstrap tab intergration

I am building a WordPress blog with bootstrap, I have used the wp_bootstrap_navwalker php to enable my wordpress menus to pass into my bootstrap code like so
<div id="navbar" class="collapse navbar-collapse" style="background-color: #333;">
<div class="container">
<ul class="nav navbar-nav">
<?php
/* Primary navigation */
wp_nav_menu(array(
'menu' => 'Primary Menu',
'theme_location' => 'locations-primary',
'depth' => 2,
'container' => false,
'container_class' => 'collapse navbar-collapse',
'container_id' => 'bs-example-navbar-collapse-1',
'menu_class' => 'nav navbar-nav',
'fallback_cb' => 'wp_bootstrap_navwalker::fallback',
'walker' => new wp_bootstrap_navwalker())
);
?>
</ul>
</div>
</div>
This works well, although now im trying to build a tab menu using the menu system above like so
<div class="container">
<ul class="nav navbar-nav">
<div class="row text-center" id="tabs">
<?php
/* Secondary navigation */
wp_nav_menu(array(
'menu' => 'Secondary Menu',
'theme_location' => 'locations-secondary',
'depth' => 2,
'container' => false,
'container_class' => 'collapse navbar-collapse',
'container_id' => 'bs-example-navbar-collapse-1',
'menu_class' => 'nav navbar-nav',
'fallback_cb' => 'wp_bootstrap_navwalker::fallback',
'walker' => new wp_bootstrap_navwalker())
);
?>
</div>
</ul>
</div>
and tab content
<div class="row text-center" id="tabs">
<?php get_template_part('advicecentre_bar', get_post_format());>
<div class="tab-content">
<div class="tab-pane active" id="tab1">
<?php
$id = 177;
$post = get_post($id);
$title = apply_filters('the_title', $post->post_title);
$content = apply_filters('the_content', $post->post_content);
echo '<h1>' . $title . '</h1><hr>';
echo $content;
?>
</div>
<div class="tab-pane" id="tab2">
<?php
$id = 2;
$post = get_post($id);
$title = apply_filters('the_title', $post->post_title);
$content = apply_filters('the_content', $post->post_content);
echo '<h1>' . $title . '</h1><hr>';
echo $content;
?>
</div>
<div class="tab-pane" id="tab3">
<?php
$id = 168;
$post = get_post($id);
$title = apply_filters('the_title', $post->post_title);
$content = apply_filters('the_content', $post->post_content);
echo '<h1>' . $title . '</h1><hr>';
echo $content;
?>
</div>
</div>
</div>
within the wordpress menu cms i have created custom links and given a URL such as URL #tab1 however I am missing data-toggle="tab"to get the tabs working, I can not see a way to do this through the CMS dose anyone know how I can get this working.
UPDATE
Ok so I am trying to edit the following code to say if menu_class is nav nav-tabs then append data-toggle="tab" in the <a> need some help doing this
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">' . esc_attr( $item->title ) . '';
} 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';
// $atts['data-toggle'] = 'elementscroll';
} 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;
Link to wp_bootstrap_navwalker

WP Add Attributes and HTML in Menu

How can I use walker in wp navigation system if I want to add something in menu if that item has child items, I'm using following code-
<?php
wp_nav_menu(array(
'menu' => '',
'container' => 'ul',
'container_class' => '',
'container_id' => '',
'menu_class' => 'nav navbar-nav',
'menu_id' => 'menu-main-menu',
'echo' => true,
'before' => '',
'after' => '',
'link_before' => '',
'link_after' => '',
'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>',
'walker' => '',
'theme_location' => 'header_menu'
)); ?>
and my result is something like
<ul id="menu-main-menu" class="nav navbar-nav">
<li id="menu-item-16" class="menu-item menu-item-type-custom menu-item-object-custom current-menu-item current_page_item menu-item-home menu-item-has-children dropdown menu-item-16">
Home
<ul class="sub-menu">
<li id="menu-item-18" class="menu-item menu-item-type-post_type menu-item-object-services menu-item-18">Something</li>
</ul>
</li>
<li id="menu-item-17" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-17">Sample Page</li>
</ul>
But I need to replace <ul class="sub-menu"> with <ul role="menu" class=" dropdown-menu"> and Home with Home <i class="fa fa-angle-down"></i>
You can do this by extending the walker like so:
class custom_sub_walker extends Walker_Nav_Menu {
public function start_lvl( &$output, $depth = 0, $args = array() ) {
$indent = str_repeat( "\t", $depth );
$output .= "\n$indent<ul role=\"menu\" class=\" dropdown-menu\">\n";
}
public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
$class_names = $value = '';
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
$classes[] = 'menu-item-' . $item->ID;
/*grab the default wp nav classes*/
$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
/*if the current item has children, append the dropdown class*/
if ( $args->has_children )
$class_names .= ' dropdown';
/*if there aren't any class names, don't show class attribute*/
$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 the current menu item has children and it's the parent, set the dropdown attributes*/
if ( $args->has_children && $depth === 0 ) {
$atts['href'] = '#';
$atts['data-toggle'] = 'dropdown';
$atts['class'] = 'dropdown-toggle';
} 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;
$item_output .= '<a'. $attributes .'>';
$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
/* if the current menu item has children and it's the parent item, append the fa-angle-down icon*/
$item_output .= ( $args->has_children && $depth === 0 ) ? ' <i class="fa fa-angle-down"></i></a>' : '</a>';
$item_output .= $args->after;
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
if ( ! $element )
return;
$id_field = $this->db_fields['id'];
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 );
}
}
Create a file called custom_walker.php with the code above in your themes folder and import it into functions.php with require_once('custom_walker.php');, or paste the class into functions.php.
Then call your menu:
<?php
wp_nav_menu( array(
'menu_class' => 'nav navbar-nav',
'menu_id' => 'menu-main-menu',
'theme_location' => 'header_menu'
'walker' => new custom_sub_walker(),
) );
?>

Custom menu Wordpress: add attribute data-letters="link name"

I have a custom menu :
function mfn_wp_nav_menu() {
$args = array(
'container' => 'nav',
'container_id' => 'menu',
'menu_class' => 'menu',
'fallback_cb' => 'mfn_wp_page_menu',
'depth' => 5,
'link_before' => '<span>',
'link_after' => '</span>',
);
}
And the input in HTML is :
<li id="id" class="class">
<a href="#" data-hash="">
<span>Start</span>
</a>
</li>
But I want to add data-letters="Link name", so for example :
<li id="id" class="class">
<a href="#" data-hash="">
<span data-letters="Start">Start</span>
</a>
</li>
Any Idea ?
You can extend the Walker menu class like this:
class MyMenu extends Walker {
function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
$output .= sprintf( "\n<li><a href='%s'%s><span data-letters='%s'>%s</span></a></li>\n",
$item->url,
( $item->object_id === get_the_ID() ) ? ' class="current"' : '',
$item->title,
$item->title
);
}
}
And apply it to your menu:
wp_nav_menu(array(
'menu' => 2, // menu id
'walker' => new MyMenu()
// your other options
));
See this example from the reference: here

Changing menu <li> to <dd> with wp_nav_menu

I created a theme in HTML using Zurb Foundation and then integrated it into a WordPress theme.
The primary nav section in my theme, in its most basic form is:
<dl>
<dd></dd>
<dd></dd>
<dd></dd>
</dl>
I configured wordpress's menu call as such:
wp_nav_menu( array(
'theme_location' => 'primary',
'menu' => '',
'container' => '',
'container_class' => '',
'container_id' => '',
'menu_class' => 'menu',
'menu_id' => '',
'echo' => true,
'fallback_cb' => 'wp_page_menu',
'before' => '',
'after' => '',
'link_before' => '',
'link_after' => '',
'items_wrap' => '<dl id="tabnav" class="sub-nav">%3$s</dl>',
'depth' => 0,
'walker' => '') );
But in order to change the wrapping <li> that wordpress puts out to a <dd> I would need to write a custom walker.
I looked through some custom walkers and can see parts of the logic, but is creating a class every time I want to use custom html for a menu the only/most efficient way to go about it?
digwp provides an easier approach than the walker
create a function that builds the menu from scratch.
in your functions.php
// custom menu example # http://digwp.com/2011/11/html-formatting-custom-menus/
function clean_custom_menus() {
$menu_name = 'nav-primary'; // specify custom menu slug
if (($locations = get_nav_menu_locations()) && isset($locations[$menu_name])) {
$menu = wp_get_nav_menu_object($locations[$menu_name]);
$menu_items = wp_get_nav_menu_items($menu->term_id);
$menu_list = '<dl>' ."\n";
foreach ((array) $menu_items as $key => $menu_item) {
$title = $menu_item->title;
$url = $menu_item->url;
$menu_list .= "\t\t\t\t\t". '<dd>'. $title .'</dd>' ."\n";
}
$menu_list .= "\t\t\t". '</dl>' ."\n";
} else {
// $menu_list = '<!-- no list defined -->';
}
echo $menu_list;
}
and to call it in your theme:
<?php if (function_exists(clean_custom_menus())) clean_custom_menus(); ?>
so you would have to edit the $menu_name to your menu slug.
here's the source

Categories