How do I mix HTML element types for a two-menu navbar?
I am building a WordPress theme with Bootstrap 4.
WordPress' menu contents should be sourced from the Menus options, output in to a Bootstrap 4 navbar. I am using this Bootstrap 4-specific wp_nav_menu
navwalker ...
require_once get_template_directory() . '/inc/bs4navwalker.php';
... to output the primary menu of nav text links as an unordered list, just as God intended...
<!-- Navbar .1/components/navbar/ -->
<nav class="navbar navbar-expand-md navbar-light"><!-- collapse at stated breakpoint -->
<a class="navbar-brand" href="<?php echo esc_url( home_url( '/' ) ); ?>">
<img src=".gif" height="30" class="d-inline-block align-top mr-1">
<?php bloginfo( 'name' ); ?>
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#bs4navbar" aria-controls="bs4navbar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<?php
wp_nav_menu([ // bs4navwalker menu generator
'menu' => 'primary', // name of wordpress menu
'theme_location' => 'primary',
'depth' => 2,
// <nav>:
// 'container' => 'false',
'container_id' => 'bs4navbar',
'container_class' => 'collapse navbar-collapse',
// <ul>:
'menu_id' => false,
'menu_class' => 'navbar-nav ml-auto',
// other:
'fallback_cb' => 'bs4navwalker::fallback',
'walker' => new bs4navwalker()
]);
?>
<button class="btn btn-outline-primary mx-3" type="submit">Button</button>
<button class="btn btn-primary ml-3" type="submit">Sign up</button>
</nav>
That works fine. Output is...
<nav class="navbar navbar-expand-md navbar-light"><!-- collapse at stated breakpoint -->
<a class="navbar-brand" href="/">
<img src=".gif" height="30" class="d-inline-block align-top mr-1">
Sandbox </a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#bs4navbar" aria-controls="bs4navbar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div id="bs4navbar" class="collapse navbar-collapse">
<ul id="menu-my-menu" class="navbar-nav ml-auto">
<li id="menu-item-3" class="menu-item menu-item-type-custom menu-item-object-custom current-menu-item current_page_item menu-item-home menu-item-3 nav-item mx-3 active"><a title="Home Page" href="/" class="nav-link active" aria-expanded="false"><i class="icon-speedometer"></i>Home</a></li>
<li id="menu-item-4" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-4 nav-item mx-3"><a title="Example Page" href="/" class="nav-link" aria-expanded="false"><i class="ti-layout-grid2"></i>Trends</a></li>
<li id="menu-item-5" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-5 nav-item mx-3"><a title="Custom Page" href="/" class="nav-link" aria-expanded="false"><i class="ti-palette"></i>Custom</a></li>
<li id="menu-item-14" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-14 nav-item mx-3"><a href="#" class="nav-link" aria-expanded="false">Strategy</a></li>
</ul>
</div>
<button class="btn btn-outline-primary mx-3" type="submit">Button</button>
<button class="btn btn-primary ml-3" type="submit">Sign up</button>
</nav>
However, you'll see the portion in which I have manually inserted two <button>
elements. Instead of hard-coding, I want these to be dynamically generated from a WordPress menu, just like the primary
menu.
I have made a second WordPress menu, buttons
. This is where I am breaking down...
I can insert a second wp_nav_menu
call for buttons
, right after the first one for primary
...
<?php
wp_nav_menu([ // bs4navwalker menu generator
'menu' => 'buttons', // name of wordpress menu
'theme_location' => 'buttons',
'depth' => 2,
// <nav>:
// 'container' => 'false',
'container_id' => 'bs4navbar',
'container_class' => 'collapse navbar-collapse',
// <ul>:
'menu_id' => false,
'menu_class' => 'navbar-nav ml-auto',
// other:
'fallback_cb' => 'bs4navwalker::fallback',
'walker' => new bs4navwalker()
]);
?>
... and the menu items will get inserted in the right place.
The problem is, those items are <li>
s inside a <ul>
, just like the primary
menu...
I assume bs4navwalker is set up to output all wp_nav_menu
items as list items, or maybe that's WordPress' doing.
How can I see to it that the items from the second menu, buttons
, get output using different HTML construction, as <button>
elements instead?
How do I mix HTML element types for a two-menu navbar?
I am building a WordPress theme with Bootstrap 4.
WordPress' menu contents should be sourced from the Menus options, output in to a Bootstrap 4 navbar. I am using this Bootstrap 4-specific wp_nav_menu
navwalker ...
require_once get_template_directory() . '/inc/bs4navwalker.php';
... to output the primary menu of nav text links as an unordered list, just as God intended...
<!-- Navbar https://getbootstrap.com/docs/4.1/components/navbar/ -->
<nav class="navbar navbar-expand-md navbar-light"><!-- collapse at stated breakpoint -->
<a class="navbar-brand" href="<?php echo esc_url( home_url( '/' ) ); ?>">
<img src="https://www.example.com/logo.gif" height="30" class="d-inline-block align-top mr-1">
<?php bloginfo( 'name' ); ?>
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#bs4navbar" aria-controls="bs4navbar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<?php
wp_nav_menu([ // bs4navwalker menu generator
'menu' => 'primary', // name of wordpress menu
'theme_location' => 'primary',
'depth' => 2,
// <nav>:
// 'container' => 'false',
'container_id' => 'bs4navbar',
'container_class' => 'collapse navbar-collapse',
// <ul>:
'menu_id' => false,
'menu_class' => 'navbar-nav ml-auto',
// other:
'fallback_cb' => 'bs4navwalker::fallback',
'walker' => new bs4navwalker()
]);
?>
<button class="btn btn-outline-primary mx-3" type="submit">Button</button>
<button class="btn btn-primary ml-3" type="submit">Sign up</button>
</nav>
That works fine. Output is...
<nav class="navbar navbar-expand-md navbar-light"><!-- collapse at stated breakpoint -->
<a class="navbar-brand" href="http://www.example.com/">
<img src="https://www.example.com/logo.gif" height="30" class="d-inline-block align-top mr-1">
Sandbox </a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#bs4navbar" aria-controls="bs4navbar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div id="bs4navbar" class="collapse navbar-collapse">
<ul id="menu-my-menu" class="navbar-nav ml-auto">
<li id="menu-item-3" class="menu-item menu-item-type-custom menu-item-object-custom current-menu-item current_page_item menu-item-home menu-item-3 nav-item mx-3 active"><a title="Home Page" href="http://sandbox.contexthq.com/" class="nav-link active" aria-expanded="false"><i class="icon-speedometer"></i>Home</a></li>
<li id="menu-item-4" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-4 nav-item mx-3"><a title="Example Page" href="http://example.com/" class="nav-link" aria-expanded="false"><i class="ti-layout-grid2"></i>Trends</a></li>
<li id="menu-item-5" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-5 nav-item mx-3"><a title="Custom Page" href="http://example.com/custom/" class="nav-link" aria-expanded="false"><i class="ti-palette"></i>Custom</a></li>
<li id="menu-item-14" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-14 nav-item mx-3"><a href="#" class="nav-link" aria-expanded="false">Strategy</a></li>
</ul>
</div>
<button class="btn btn-outline-primary mx-3" type="submit">Button</button>
<button class="btn btn-primary ml-3" type="submit">Sign up</button>
</nav>
However, you'll see the portion in which I have manually inserted two <button>
elements. Instead of hard-coding, I want these to be dynamically generated from a WordPress menu, just like the primary
menu.
I have made a second WordPress menu, buttons
. This is where I am breaking down...
I can insert a second wp_nav_menu
call for buttons
, right after the first one for primary
...
<?php
wp_nav_menu([ // bs4navwalker menu generator
'menu' => 'buttons', // name of wordpress menu
'theme_location' => 'buttons',
'depth' => 2,
// <nav>:
// 'container' => 'false',
'container_id' => 'bs4navbar',
'container_class' => 'collapse navbar-collapse',
// <ul>:
'menu_id' => false,
'menu_class' => 'navbar-nav ml-auto',
// other:
'fallback_cb' => 'bs4navwalker::fallback',
'walker' => new bs4navwalker()
]);
?>
... and the menu items will get inserted in the right place.
The problem is, those items are <li>
s inside a <ul>
, just like the primary
menu...
I assume bs4navwalker is set up to output all wp_nav_menu
items as list items, or maybe that's WordPress' doing.
How can I see to it that the items from the second menu, buttons
, get output using different HTML construction, as <button>
elements instead?
The following is a solution, though uses extra PHP processing...
<?php
$options = array(
'echo' => false,
'theme_location' => 'buttons',
'items_wrap' => '%3$s',
'menu_class' => false,
'menu_id' => false,
'container' => 'false',
'container_class' => false,
'container_id' => false,
'before' => '<button class="btn btn-primary mx-3 d-none d-md-block" type="submit">',
'after' => '</button>'
);
$menu = wp_nav_menu($options);
$output = strip_tags($menu, '<button>');
echo preg_replace('/btn-primary/', 'btn-outline-primary', $output, 1);
?>
This involves:
<ul>
<button>
tag<li>
) except <button>
)btn-primary
class with btn-outline-primary
, in order to retain buttons of two colours.Here is the output...
<button class="btn btn-outline-primary mx-3 d-none d-md-block" type="submit">Button</button>
<button class="btn btn-primary mx-3 d-none d-md-block" type="submit">Learn More</button>
I would have preferred to set the button colour classes using WordPress' own functionality for setting Menu item classes, rather than hard-code them here.
Is there a way to get those classes appearing in the nav item, instead of using preg_replace
, or would this method not support it?
<button>
elements are inappropriate for links, so there isn't really anything you could add to a menu that would make sense for a button element. – Jacob Peattie Commented Aug 20, 2018 at 12:20<button>
element for styling reasons then you're doing this all wrong. – Jacob Peattie Commented Aug 20, 2018 at 14:22