1

I am using the following filter to select <a> tags from a specific menu that have no attributes (href, class, etc.) and replace them with <button> tags.

add_filter( 'wp_nav_menu_items', 'filter_empty_anchor_items', 10, 2 );
function filter_empty_anchor_items( $items, $args ) {
  if( $args->theme_location == 'want-to-navigation')  {
    $pattern = '/<a>(.*?)<\/a>/s';
    $items = preg_replace($pattern, '<button>$1</button>', $items );
  }
  return $items;
}

The filter itself is working, but I need to adjust the regular expression or run a second pass of a separate regular expression to select the text within the <button> tag and wrap it with a <span> tag.

The following wp_nav_menu code is being used to display the menu with a <svg> attached to the link_after argument.

$args = array(
  "theme_location" => "want-to-navigation",
  "menu_id" => "want-to-navigation",
  "container" => "false",
  "container_id" => "want-to",
  "container_class" => "quicklinks",
  "link_after" => '<svg viewBox="0 0 448 512" xmlns="http://www.w3.org/2000/svg"><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>',
);
echo wp_nav_menu( $args );

An example: Select <button>Select this text and wrap with span<svg></svg></button>

1
  • Have you looked into a custom nav walker? That would likely give you even more control over the markup and probably not require regexes.
    – WebElaine
    Commented Jun 8, 2022 at 14:21

2 Answers 2

1

Just use link_before in your wp_nav_menu $args and add opening/closing span tags:

$args = [
    'link_before' => '<span>',
    /* Add closing </span> to link_after */
    'link_after' => '</span><svg>...</svg>',

    // Other args
];
1
  • Thanks. I used your solution in combination with an adjusted preg_replace pattern to achieve my needs. Commented Jun 8, 2022 at 16:09
0

Here is my solution with assistance from TheDeadMedic.

I added the <svg> code to the replacement value in the preg_replace function, then added the opening and closing <span> tags to the link_before and link_after arguments in the theme template file.

Nav menu items filter

add_filter( 'wp_nav_menu_items', 'filter_empty_anchor_items', 10, 2 );
function filter_empty_anchor_items( $items, $args ) {
  if( $args->theme_location == 'want-to-navigation') {
    $pattern = '/<a>(.*?)<\/a>/s';
    $replacement = '<button>$1<svg viewBox="0 0 448 512" xmlns="http://www.w3.org/2000/svg"><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;
}

Nav menu output

$args = array(
  "theme_location" => "want-to-navigation",
  "menu_id" => "want-to-navigation",
  "container" => "false",
  "container_id" => "want-to",
  "container_class" => "quicklinks",
  "link_before" => '<span>',
  "link_after" => '</span>',
);

I hope this is helpful to others needing to achieve something similar.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.