0

So, I am trying to change the DOM structure of a wordpress menu based on if the class submenu-item exists on an li. What I would like to do is change it so that <li class="submenu"><ul> is before the group of li's and </ul></li> comes after the group of li's with the class submenu-item.

For example: Here's a string that I need to manipulate (possibly with REGEX):

<li id="menu-item-5" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-has-description menu-item-5 dropdown"><a data-toggle="dropdown" class="dropdown-toggle" aria-haspopup="true">Community Living <span class="caret-arrow"></span></a>
    <ul role="menu" class="mega-menu dropdown-menu">
        <li id="menu-item-1000106" class="d-none d-md-block menu-item-description menu-item-1000106">
            <h3>Community Living</h3>
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed fringilla ac nulla vel venenatis.</p>
        </li>
        <li id="menu-item-6" class="menu-item menu-item-type-custom menu-item-object-custom d-md-inline-block menu-item-6 submenu-item"><a href="#">Child 1</a></li>
        <li id="menu-item-7" class="menu-item menu-item-type-custom menu-item-object-custom d-md-inline-block menu-item-7 submenu-item"><a href="#">Child 2</a></li>
    </ul>
</li>
<li id="menu-item-8" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-has-image menu-item-has-description menu-item-8 dropdown">
    <a data-toggle="dropdown" class="dropdown-toggle" aria-haspopup="true">Aging in Place <span class="caret-arrow"></span></a>
    <ul role="menu" class="mega-menu dropdown-menu">
        <li id="menu-item-1000110" class="menu-item menu-item-custom menu-item-image col-7 d-none d-md-inline-block p-0 menu-item-1000110"><img src="http://levlane-bootstrap.local/wp-content/uploads/2020/08/menu-image-152x214.jpg" alt="" class="img-fluid menu-image" /></li>
        <li class="d-none d-md-block menu-item-description menu-item-1000110">
            <h3>Aging in Place</h3>
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed fringilla ac nulla vel venenatis.</p>
        </li>
        <li id="menu-item-9" class="menu-item menu-item-type-custom menu-item-object-custom d-md-inline-block menu-item-9 submenu-item"><a href="#">Child 1</a></li>
        <li id="menu-item-10" class="menu-item menu-item-type-custom menu-item-object-custom d-md-inline-block menu-item-10 submenu-item"><a href="#">Child 2</a></li>
        <li id="menu-item-11" class="menu-item menu-item-type-custom menu-item-object-custom d-md-inline-block menu-item-11 submenu-item"><a href="#">Child 3</a></li>
    </ul>
</li>
<li id="menu-item-12" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-has-image menu-item-has-description menu-item-12 dropdown">
    <a data-toggle="dropdown" class="dropdown-toggle" aria-haspopup="true">Caregiver Services <span class="caret-arrow"></span></a>
    <ul role="menu" class="mega-menu dropdown-menu">
        <li id="menu-item-1000115" class="menu-item menu-item-custom menu-item-image col-7 d-none d-md-inline-block p-0 menu-item-1000115"><img src="http://levlane-bootstrap.local/wp-content/uploads/2020/08/menu-image-152x214.jpg" alt="" class="img-fluid menu-image" /></li>
        <li class="d-none d-md-block menu-item-description menu-item-1000115">
            <h3>Caregiver Services</h3>
            <p>Testing a Description without an Image just to see how it shows.  Hopefully fine.</p>
        </li>
        <li id="menu-item-126" class="menu-item menu-item-type-custom menu-item-object-custom d-md-inline-block menu-item-126 submenu-item"><a href="#">Testing</a></li>
    </ul>
</li>
<li id="menu-item-1000107" class="menu-item menu-item-type-logo d-none d-md-flex menu-item-1000107"><a href="/"><img src="http://levlane-bootstrap.local/wp-content/uploads/2020/07/logo.png" alt="" width="194" height="80" /></a></li>
<li id="menu-item-111" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-has-image menu-item-has-description menu-item-111 dropdown">
    <a data-toggle="dropdown" class="dropdown-toggle" aria-haspopup="true">Healthcare Center <span class="caret-arrow"></span></a>
    <ul role="menu" class="mega-menu dropdown-menu">
        <li id="menu-item-1000215" class="menu-item menu-item-custom menu-item-image col-7 d-none d-md-inline-block p-0 menu-item-1000215"><img src="http://levlane-bootstrap.local/wp-content/uploads/2020/08/menu-image-152x214.jpg" alt="" class="img-fluid menu-image" /></li>
        <li class="d-none d-md-block menu-item-description menu-item-1000215">
            <h3>Healthcare Center</h3>
            <p>Fusce eleifend diam sit amet ipsum iaculis, at sollicitudin risus fermentum. Sed egestas urna ac neque ullamcorper lacinia sed tempus tellus</p>
        </li>
        <li id="menu-item-130" class="menu-item menu-item-type-custom menu-item-object-custom d-md-inline-block menu-item-130 submenu-item"><a href="#">Child 1</a></li>
    </ul>
</li>

How could I implement a string replacement so that if submenu-item is found it adds html before and after the group of lis here?

For Example, would like to change it so that it looks like this instead:

<li id="menu-item-5" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-has-description menu-item-5 dropdown"><a data-toggle="dropdown" class="dropdown-toggle" aria-haspopup="true">Community Living <span class="caret-arrow"></span></a>
    <ul role="menu" class="mega-menu dropdown-menu">
        <li id="menu-item-1000106" class="d-none d-md-block menu-item-description menu-item-1000106">
            <h3>Community Living</h3>
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed fringilla ac nulla vel venenatis.</p>
        </li>
        <li class="submenu">
            <ul>
                <li id="menu-item-6" class="menu-item menu-item-type-custom menu-item-object-custom d-md-inline-block menu-item-6 submenu-item"><a href="#">Child 1</a></li>
                <li id="menu-item-7" class="menu-item menu-item-type-custom menu-item-object-custom d-md-inline-block menu-item-7 submenu-item"><a href="#">Child 2</a></li>
            </ul>
        </li>
    </ul>
</li>
<li id="menu-item-8" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-has-image menu-item-has-description menu-item-8 dropdown">
    <a data-toggle="dropdown" class="dropdown-toggle" aria-haspopup="true">Aging in Place <span class="caret-arrow"></span></a>
    <ul role="menu" class="mega-menu dropdown-menu">
        <li id="menu-item-1000110" class="menu-item menu-item-custom menu-item-image col-7 d-none d-md-inline-block p-0 menu-item-1000110"><img src="http://levlane-bootstrap.local/wp-content/uploads/2020/08/menu-image-152x214.jpg" alt="" class="img-fluid menu-image" /></li>
        <li class="d-none d-md-block menu-item-description menu-item-1000110">
            <h3>Aging in Place</h3>
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed fringilla ac nulla vel venenatis.</p>
        </li>
        <li class="submenu">
            <ul>
                <li id="menu-item-9" class="menu-item menu-item-type-custom menu-item-object-custom d-md-inline-block menu-item-9 submenu-item"><a href="#">Child 1</a></li>
                <li id="menu-item-10" class="menu-item menu-item-type-custom menu-item-object-custom d-md-inline-block menu-item-10 submenu-item"><a href="#">Child 2</a></li>
                <li id="menu-item-11" class="menu-item menu-item-type-custom menu-item-object-custom d-md-inline-block menu-item-11 submenu-item"><a href="#">Child 3</a></li>
            </ul>
        </li>
    </ul>
</li>
<li id="menu-item-12" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-has-image menu-item-has-description menu-item-12 dropdown">
    <a data-toggle="dropdown" class="dropdown-toggle" aria-haspopup="true">Caregiver Services <span class="caret-arrow"></span></a>
    <ul role="menu" class="mega-menu dropdown-menu">
        <li id="menu-item-1000115" class="menu-item menu-item-custom menu-item-image col-7 d-none d-md-inline-block p-0 menu-item-1000115"><img src="http://levlane-bootstrap.local/wp-content/uploads/2020/08/menu-image-152x214.jpg" alt="" class="img-fluid menu-image" /></li>
        <li class="d-none d-md-block menu-item-description menu-item-1000115">
            <h3>Caregiver Services</h3>
            <p>Testing a Description without an Image just to see how it shows.  Hopefully fine.</p>
        </li>
        <li class="submenu">
            <ul>
                <li id="menu-item-126" class="menu-item menu-item-type-custom menu-item-object-custom d-md-inline-block menu-item-126 submenu-item"><a href="#">Testing</a></li>
            </ul>
        </li>
    </ul>
</li>
<li id="menu-item-1000107" class="menu-item menu-item-type-logo d-none d-md-flex menu-item-1000107"><a href="/"><img src="http://levlane-bootstrap.local/wp-content/uploads/2020/07/logo.png" alt="" width="194" height="80" /></a></li>
<li id="menu-item-111" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-has-image menu-item-has-description menu-item-111 dropdown">
    <a data-toggle="dropdown" class="dropdown-toggle" aria-haspopup="true">Healthcare Center <span class="caret-arrow"></span></a>
    <ul role="menu" class="mega-menu dropdown-menu">
        <li id="menu-item-1000215" class="menu-item menu-item-custom menu-item-image col-7 d-none d-md-inline-block p-0 menu-item-1000215"><img src="http://levlane-bootstrap.local/wp-content/uploads/2020/08/menu-image-152x214.jpg" alt="" class="img-fluid menu-image" /></li>
        <li class="d-none d-md-block menu-item-description menu-item-1000215">
            <h3>Healthcare Center</h3>
            <p>Fusce eleifend diam sit amet ipsum iaculis, at sollicitudin risus fermentum. Sed egestas urna ac neque ullamcorper lacinia sed tempus tellus</p>
        </li>
        <li class="submenu">
            <ul>
                <li id="menu-item-130" class="menu-item menu-item-type-custom menu-item-object-custom d-md-inline-block menu-item-130 submenu-item"><a href="#">Child 1</a></li>
            </ul>
        </li>
    </ul>
</li>

Hopefully, this makes sense, basically, just want to wrap the group of lis that have submenu-item listed in the class name within a <li /><ul /> tags.

Is this possible to do and thinking that regex can help here, but not sure how. I am using the wp_nav_menu_items wordpress filter, since the wp_navwalker class doesn't provide any easy way to do this that I can see. This is the only hook that actually provides decent manipulation of the dom, unless I'm overlooking someway of doing this with a different wordpress hook or something?

Solomon Closson
  • 6,111
  • 14
  • 73
  • 115
  • what have you tried so far? – Professor Abronsius Aug 05 '20 at 06:51
  • I'm still trying to think if this approach is feasible. I have tried using a custom navwalker class, but thinking it might be better to use the `wp_nav_menu_objects` filter, checking for children when looping through the nav items and setting a property on the first and last items that gets passed to the $items array that might be useful in the navwalker class. Your thoughts? – Solomon Closson Aug 05 '20 at 07:11
  • I'm not really good with regex's as it's very difficult for me to wrap my head around. So I'm wondering if it's even possible with a reg ex to begin with. – Solomon Closson Aug 05 '20 at 07:12
  • Using a `regEx` would not, in my opinion, be the best method - I would suggest using `DOMDocument` – Professor Abronsius Aug 05 '20 at 07:27
  • Could you not just change the order in the admin? If this theme is being used by anyone other than yourself, taking away the default WP functionality of being able to decide the order themselves is bad practice (and very annoying for the user). If you *must* change it, then the best way would be to rebuild the menu HTML yourself ,rather than build it and then try to manipulate it into a different structure. – FluffyKitten Aug 05 '20 at 09:52

0 Answers0