I have the following lines of HTML that I am needing to use preg_replace
or a similar function to add a button
element that can be used for JavaScript events.
<li id="" >
<a href="https://example.com">Parent Menu Item</a>
<!-- Add button HTML element here -->
<ul >
<!-- Child menu items -->
</ul>
</li>
Pattern idea:
$pattern = '/<li id="(.*?)" ><a href="(.*?)">(.*?)<\/a><ul >(.*?)<\/ul><\/li>/s';
Only li
elements that have the menu-item-has-children
class should be used.
I have used the following WordPress filter function to find and replace anchor elements that do not have a href
attribute, but have been unable to modify it to successfully add a button
element between the anchor elements and sub-menu
unordered lists.
add_filter( 'wp_nav_menu_items', 'themename_filter_empty_anchor_items', 10, 2 );
function themename_filter_empty_anchor_items( $items, $args ) {
if( $args->theme_location == 'want-to-navigation') {
$pattern = '/<a>(.*?)<\/a>/s';
$replacement = '<button aria-expanded="false" data-submenu-toggle="">$1<svg role="img" viewBox="0 0 448 512" xmlns="http://www.w3.org/2000/svg"><title>Expand submenu navigation icon</title><path d="m432 256c0 17.69-14.33 32.01-32 32.01h-144v144c0 17.69-14.33 31.99-32 31.99s-32-14.3-32-31.99v-144h-144c-17.67 0-32-14.32-32-32.01s14.33-31.99 32-31.99h144v-144c0-17.69 14.33-32.01 32-32.01s32 14.32 32 32.01v144h144c17.7-.01 32 14.29 32 31.99z"/></svg></button>';
$items = preg_replace( $pattern, $replacement, $items );
}
return $items;
}
CodePudding user response:
You could use DOMDocument
in conjunction with DOMXPath
to load your HTML, find the appropriate a
element and then append a button after it:
$html = <<<EOD
<li id="" >
<a href="https://example.com">Parent Menu Item</a>
<!-- Add button HTML element here -->
<ul >
<!-- Child menu items -->
</ul>
</li>
EOD;
$doc = new DOMDocument();
$doc->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($doc);
foreach ($xpath->query('//li[@]/a') as $a) {
$button = $doc->createElement('button', 'Your button text');
// modify button as required
// ...
// add to document
$a->parentNode->insertBefore($button, $a->nextSibling);
}
echo $doc->saveHTML();
Output:
<li id="" >
<a href="https://example.com">Parent Menu Item</a><button>Your button text</button>
<!-- Add button HTML element here -->
<ul >
<!-- Child menu items -->
</ul>
</li>
CodePudding user response:
I followed CBroe's suggestion and utilized JavaScript to insert the button
elements between the a
and ul
elements.
The code below details what I implemented. A matchMedia method was used to target the code at screens smaller than 1169 pixels.
const mediaQuery = window.matchMedia('(max-width: 1169px)');
if (mediaQuery.matches) {
let links = document.querySelectorAll("#global-navigation .menu-item-has-children > a");
links.forEach(function (link) {
let linkExpander = document.createElement("button");
linkExpander.setAttribute("aria-expanded", "false");
linkExpander.setAttribute("data-submenu-toggle", "");
let svg = `<svg role="img" viewBox="0 0 448 512" xmlns="http://www.w3.org/2000/svg"><title>Expand submenu navigation icon</title><path d="m432 256c0 17.69-14.33 32.01-32 32.01h-144v144c0 17.69-14.33 31.99-32 31.99s-32-14.3-32-31.99v-144h-144c-17.67 0-32-14.32-32-32.01s14.33-31.99 32-31.99h144v-144c0-17.69 14.33-32.01 32-32.01s32 14.32 32 32.01v144h144c17.7-.01 32 14.29 32 31.99z"></path></svg>`;
linkExpander.insertAdjacentHTML("beforeend", svg);
link.after(linkExpander);
});
}