Reputation: 1187
Scenario:
I want to faciliate the user to choose from two different menus to be used as his/her primary menu.
I created two menus, and an Entry in both menus to switch to each other (Switch to B) (Switch to A).
The idea is that when a menu item is pressed, a wordpress function is called to switch the menu. Since I have already created the menus, they have specific IDs to choose from. All I want to hook specific function on clicking the (menu entries created in each menu) to swap the primary menu.
------------ EDIT ------------
My Approach
My Approach so far is as follows.
Created a template named Menu_Switch
and created a wordpress page based on that template.
Called a function in that template.
I created the menu entry with that newly created page in both menus.
The function is as follows.
function switch_menu ( $args = '' ) {
if( $args['theme_location'] == 'primary') {
if ($args['menu'] == '45') {
$args['menu'] = '65';
} else if ($args['menu'] == '65') {
$args['menu'] = '45';
}
return $args;
}
$redirect = home_url();
}
AND then called the function in the template like this
<?php echo switch_menu(); ?>
Question
This code is not working as expected. Following is expected.
primary menu
is 45
, it should set it to 65
and vise-versa.Upvotes: 1
Views: 1106
Reputation: 9693
I think you are searching for a filter where you can toggle your main menu.
If you will go through wp_nav_menu() source code
There is a filter $args = apply_filters( 'wp_nav_menu_args', $args );
and this $args array structure is
$defaults = array(
'menu' => '',
'container' => 'div',
'container_class' => '',
'container_id' => '',
'container_aria_label' => '',
'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>',
'item_spacing' => 'preserve',
'depth' => 0,
'walker' => '',
'theme_location' => '',
);
You can notice there is one key menu_id, if you can set that and apply this filter your menu will change based on the menu_id given.
something like
add_filter('wp_nav_menu_args', function(){
$args['menu_id'] = <desired_menu_id>
return $args;
});
Upvotes: 0
Reputation: 476
I don't think if that possible to do with way what you want - I mean changing location on fly, due it affects to whole site for all users.
You could to do it with next logic:
display: none
UPDATE
I mean that you can to create two locations and display them next to each other on frontend - and in this case you can to create two different menus and to assign to different locations. Visually it will be like two menus in one place.
And using cookie and CSS you can to display one or another menu.
UPDATE 2
Full solution(tested on real WordPress site):
register_nav_menus(
array(
'header_top_nav' => __( 'Header Top Area', 'starter' ),
'header_main_nav' => __( 'Header Main Area', 'starter' )
)
);
js_btn_show_menu_a
and js_btn_show_menu_b
which will be used for handle click in js<nav class="menu_a">
<?php
wp_nav_menu(
array(
'theme_location' => 'header_top_nav'
)
);
?>
</nav>
<nav class="menu_b">
<?php
wp_nav_menu(
array(
'theme_location' => 'header_main_nav'
)
);
?>
</nav>
$( document ).on( 'click', '.js_btn_show_menu_a', function ( e ) {
e.preventDefault();
$( 'html' ).addClass( 'show_menu_a' ).removeClass( 'show_menu_b' );
Cookies.set( 'menu', 'show_menu_a' );
})
$( document ).on( 'click', '.js_btn_show_menu_b', function ( e ) {
e.preventDefault();
$( 'html' ).addClass( 'show_menu_b' ).removeClass( 'show_menu_a' );
Cookies.set( 'menu', 'show_menu_b' );
})
<html>
$menu_cookie = htmlspecialchars( $_COOKIE['menu'] ) ? htmlspecialchars( $_COOKIE['menu'] ) : 'show_menu_a';
<html class="<?php echo esc_attr( $menu_cookie ); ?>">
.show_menu_a .menu_a {display: block;}
.show_menu_a .menu_b {display: none;}
.show_menu_b .menu_b {display: block;}
.show_menu_b .menu_a {display: none;}
Upvotes: 1