How to use buttons elements for tgetWordPress menu items?

admin2025-01-07  5

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?

Share Improve this question asked Aug 20, 2018 at 12:04 Robert AndrewsRobert Andrews 98819 silver badges42 bronze badges 3
  • What are these buttons supposed to do? The whole WordPress menu system is for adding links, but <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
  • Yes, I'm trying to bend WordPress to do something which is acceptable in modern UI terms but which it does not instinctively support. – Robert Andrews Commented Aug 20, 2018 at 13:13
  • Using button elements for links is not acceptable in 'modern UI' terms, which is why I asked what you want to use them for. If you are only using a <button> element for styling reasons then you're doing this all wrong. – Jacob Peattie Commented Aug 20, 2018 at 14:22
Add a comment  | 

1 Answer 1

Reset to default 0

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:

  • Removing <ul>
  • Not setting any containers
  • Wrapping each item in a <button> tag
  • Suppressing echo
  • Stripping all tags (ie. <li>) except <button>)
  • In the last part, replacing the first instance of the 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?

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1736263930a928.html

最新回复(0)