Change sub-menu wrap in Wordpress - php

In Wordpress, how can I add a button or div into all sub-menu li's using wp_nav_menu?
This is my current code:
<?php wp_nav_menu(array(
'theme_location' => 'main_menu',
'items_wrap'=>'%3$s',
'container' => false
)); ?>
This is my desired output:
<li class="submenu">
<a>Link 1</a>
<ul>
<li><a>Link 2</a></li>
</ul>
<button type="button">Click Me!</button>
</li>

So, Custom Walkers are a bit of a pain to work with, until you understand them.
The below custom walker code should get you what you need. Add this to your theme's functions.php file:
class Custom_Button_Walker extends Walker_Nav_Menu {
// We only care about the "end level" part of the menu, where closing </ul> tags are generated
public function end_lvl( &$output, $depth = 0, $args = array() ) {
// This is from WP core code
$indent = str_repeat("\t", $depth);
// This line ensures we only add it on the proper level
$button = (0 == $depth) ? "{$indent}<button type=\"button\">Click Me!</button>\n" : '';
// This line is modified to include the button markup
$output .= "{$indent}</ul>\n{$button}";
}
}
To use the custom walker, modify your wp_nav_menu call like so:
wp_nav_menu( array(
'theme_location' => 'main_menu',
'items_wrap' =>'%3$s',
'container' => FALSE,
'walker' => new Custom_Button_Walker()
));

Related

WordPress how to add <span> after main navigation dropdown

I like to add an empty 'span' in the main navigation li element which has a specific class.
Here is the desired look:
<ul>
<li class="menu-item"></li>
<li class="menu-item"></li>
<li class="menu-item has-childern"><span></span></li>
</ul>
I have a code that adds the span after every nav link:
add_filter('nav_menu_item_args', function ($args, $item, $depth) {
if ( $args -> theme_location == 'primary') {
$args -> link_after = '<span></span>';
}
return $args;
}, 10, 3);
How can I achieve to add the 'span' only in the 'li' element which has the 'has-children' class? Thank you for the help!
You could use nav_menu_link_attributes filter hook to get access to the nav attributes.
From Documentation
nav_menu_link_attributes
'after'
(string) Text after the link markup.
'link_after'
(string) Text after the link text.
So you could set it up in multiple ways, for example you could do something like this:
add_filter('nav_menu_link_attributes', 'your_theme_custom_html_element', 10, 3);
function your_theme_custom_html_element($atts, $item, $args)
{
if ($args->theme_location == 'primary' && (strpos($atts['class'], 'has-childern') !== false)) {
$args->after = '<span></span>';
}
return $atts;
}
Just tested on my own website and it works seamlessly fine!

How to fix my header menu changing when new menu is created?

I want to create a submenu in a page I can access from my header menu.
I created the submenu, I added a line in my "register_nav_menus".
The page I want the submenu to be has the code with the theme_location corresponding to the code added to "register_nav_menus".
Now my header menu is the submenu I just created. (I updated the location in menu's admin page).
I don't really what I can do to fix that problem. I'm pretty new to WP.
Here's the code:
FUNCTIONS.PHP
// Theme Setup
function mairie_setup() {
// Navigation resgister
register_nav_menus(
array(
'header' => __('Menu principal'),
'subnav' => __('Sous menu')
)
);
}
add_action('after_setup_theme', 'mairie_setup');
HEADER.PHP
...
<nav class="navbar">
<?php
$args = array(
'theme_location' => 'header'
);
wp_nav_menu() ?>
</nav>
...
THEME FOR SUBNAV
...
<nav class="sub_navbar">
<?php
$args = array(
'theme_location' => 'subnav'
);
wp_nav_menu() ?>
</nav>
...
I'd like my header menu to stay the header menu and not change if I create a new menu.
<nav class="navbar">
<?php
$args = array(
'theme_location' => 'header'
);
wp_nav_menu($args);
?>
</nav>
<nav class="sub_navbar">
<?php
$argss = array(
'theme_location' => 'subnav'
);
wp_nav_menu($argss);
?>
</nav>
please try this one. and read more about https://developer.wordpress.org/reference/functions/wp_nav_menu/

Walker class not found error

Hi I am using wordpress for the first time. I am trying to incorperated the walker class into my project which is located at
D:\wamp\www\SgsOnline\wp-content\themes\storefront\inc\functions\walker.php
I've included my class in my functions as
require get_template_directory() . '/inc/functions/walker.php';
And I am trying to call it in my header like :
function storefront_primary_navigation() {
?>
<nav id="site-navigation" class="main-navigation " role="navigation" aria-label="<?php esc_html_e( 'Primary Navigation', 'storefront' ); ?>">
<button class="menu-toggle" aria-controls="primary-navigation" aria-expanded="false"><?php echo esc_attr( apply_filters( 'storefront_menu_toggle_text', __( 'Navigation', 'storefront' ) ) ); ?></button>
<?php
wp_nav_menu(
array(
'theme_location' => 'primary',
'container_class' => 'primary-navigation',
'menu_class'=>'nav navbar-nav navbar-left nav-tabs',
'walker' => new Walker_Nav_Primary()
)
);
?>
</nav><!-- #site-navigation -->
<?php
}
But I am getting a error :
Fatal error: Class 'Walker_Nav_Primary' not found in
D:\wamp\www\SgsOnline\wp-content\themes\storefront\inc\structure\header.php
on line 65
This is oblivious wrong because it is looking in the wrong place for the class.
If anyone has any experience with this would be great
Regards
UPDATE
here is the class code
<?php
/* Collection of walker classes*/
class Walker_Nav_Primary extends Walker_Nav_menu {
function start_lvl( &$output, $depth){ //ul
$indent = str_repeat("\t", $depth );
$submenu = ($depth > 0) 'sub-menu' : ''; //Detect if the lvls is a submenu
$output .= "\n$indent<ul class=\"dropdown-menu$submenu depth_$depth\">\n";
}
/*
function end_lvl(){ // close ul
}
Not used at the moment
function start_el(){ // li, a, span
}
function end_el(){ // closing li, a, span
}
*/
}
At first glance it appears that file path is incorrect. / is unix directory separator but you need to use \ for Windows.
$path_elements = array(get_template_directory(), 'inc', 'functions', 'walker.php');
require join(DIRECTORY_SEPARATOR , $path_elements);
Walker_Nav_Primary has a syntax error in shorthand if-else statement (missing question mark after logical expression).
$submenu = ($depth > 0) ? 'sub-menu' : '';
I believe the issue is how you reference your walker...
'walker' => new Walker_Nav_Primary()
should just be...
'walker' => new Walker_Nav_Primary
no () needed.
If there was an issue with how you include your walker.php file that would error first as functions.php is run before your header.php.

Override Menu CSS Wordpress with Functions.php

I am using the following override in my functions.php
function wp_nav_menu_attributes_filter($var) {
return is_array($var) ? array_intersect($var, array('current-menu-item')) : '';
}
add_filter('nav_menu_css_class', 'wp_nav_menu_attributes_filter', 100, 1);
add_filter('nav_menu_item_id', 'wp_nav_menu_attributes_filter', 100, 1);
add_filter('page_css_class', 'wp_nav_menu_attributes_filter', 100, 1);
This removes the class tag that wordpress adds to a menu item. Now what I need to do is actually put in my own class name into the li tag instead, can anyone fill me in quickly on how to do that, I have scoured google and maybe I am searching for it wrong or what not or I just cannot understand the hook system with the functions.php file....
Using the above make my html output as...
<ul id="menu-homemenu" class="list-group special">
<li>Biography</li>
<li>Selected Works</li>
<li>Contact Us</li>
</ul>
Of course after I posted a comment I figured it out...sigh hate when this takes all evening to get it...this question pointed me in the right direction - How to add custom HTML to wp_nav_menu?
I added this class..
class Custom_Walker_Nav_Menu extends Walker_Nav_Menu {
function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
$output .= "<li class='list-group-item'>".esc_attr($item->title)."";
}
function end_el( &$output, $item, $depth = 0, $args = array() ) {
$output .= "</li>\n";
}
}
Then added this to my array where I called my nav inside my template...
<?php wp_nav_menu(array('menu' => 'HomeMenu','menu_class' => 'list-group special','menu_id' => '','walker' => new Custom_Walker_Nav_Menu)); ?>

wordpress custom menu class name

I wanted to add some class name of my wordpress custom menu that I created
<?php
wp_nav_menu( array(
'theme_location' => 'social-menu'
));
?>
function register_main_menus() {
register_nav_menus(array(
'social-menu' => __('Social Menu', 'sm')
));<br>
}`
`add_action('init', 'register_main_menus');`
to something like this.. I can see the option to add title attributes in admin panel but not class. How can I achieve to get those class name in each of them?
<ul>
<li></li>
<li></li>
<li></li>
</ul>
just got this one working!
function add_menuclass($ulclass) {
return preg_replace('/<a title="social-youtube-icon"/', '<a title="social-youtube-icon" class="social-youtube-icon"', $ulclass, 1);
}
add_filter('wp_nav_menu','add_menuclass');

Categories