You can use the walker_nav_menu_start_el filter:
add_filter( 'walker_nav_menu_start_el', 'wpse_add_arrow',10,4); function wpse_add_arrow( $item_output, $item, $depth, $args ){ //Only add class to 'top level' items on the 'primary' menu. if('primary' == $args->theme_location && $depth ==0){ $item_output .='<span class="arrow"></span>'; } return $item_output; }
This assumes that you're using wp_nav_menu( array( 'theme_location' => 'primary') ); to display the menu.
Updated answer in response to comments. To add the span classes to only top-level elements which have children you need to use a custom walker:
class SH_Arrow_Walker_Nav_Menu extends Walker_Nav_Menu { function start_lvl(&$output, $depth, $args) { $indent = str_repeat("\t", $depth); if('primary' == $args->theme_location && $depth ==0){ $output .='<span class="arrow"></span>'; } $output .= "\n$indent<ul class=\"sub-menu\">\n"; } }
To use this you'll need to set the walker argument in wp_nav_menu:
wp_nav_menu( array( 'theme_location' => 'primary', 'walker'=> new SH_Arrow_Walker_Nav_Menu() ) );