Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I want to apply a class to a word in my menu. For example, say I have a list item in my menu called "My Item". I would like to apply a class to the word "Item" so that I can style it anyway I want.

Do I need to add a span to the list item and then add the class to my css like this?

<div id="nav">
    <ul>
        <li><a href="/MyItem">My <span class="dark-blue">Item</span></a></li>
    </ul>
</div>

#nav ul li a.dark-blue {
    color: #00008B;
}
share|improve this question

1 Answer 1

You can filter the title of each nav menu item. Unfortunately, the filter is named 'the_title' – if we just add a simple filter for it, we may catch strings outside of nav menus too.

So we need a second function to switch our nav menu title filter on when the menu class starts and off when it ends.

Let’s start with the second function:

add_filter( 'wp_nav_menu_args', 'wpse_14037_filter_switch' );
add_filter( 'wp_nav_menu', 'wpse_14037_filter_switch' );

/**
 * Switches the registration of out title filter on and off.
 *
 * @param  mixed $input Array or string, we just pass it through.
 * @return mixed
 */
function wpse_14037_filter_switch( $input )
{
    $func = 'wp_nav_menu_args' == current_filter() ? 'add_filter' : 'remove_filter';
    $func( 'the_title', 'wpse_14037_filter_title' );
    return $input;
}

'wp_nav_menu_args' is called in wp_nav_menu() very early. When wpse_14037_filter_switch() is running in this context (current_filter) we turn the title filter on.

'wp_nav_menu' is called after all item are rendered. Now we turn the title filter off.

Now we need the wpse_14037_filter_title() we just registered:

/**
 * Adds a <span class="partNUMBER"> to each word of a menu item title.
 *
 * @param  string $title
 * @return string
 */
function wpse_14037_filter_title( $title )
{
    $title = trim( $title );
    $parts = explode( ' ', $title );
    $out   = array ();
    $i     = 1;

    foreach ( $parts as $part )
    {
        $out[] = '<span class="part' . $i++ . '">' . $part . '</span>';
    }

    return join( ' ', $out );
}

I decided to make the function more generic than you wanted it. Other people may want to style the third word … or the 15th.

To address the second word in your stylesheet just use the new class:

/* Your menu may have the class 'menu'. */
.menu .part2
{
    color: #005;
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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