0

I've read an infinite (yes there seems to be more than I care to read) same articles on how to apply a classes to the anchor not the link element using nav_menu_link_attributes and a walker.

However, none of them implement the custom class option in the menu to be utilized on the anchor. Seems like a nice feature to have to allow the user to add their own class, however, what if I want to apply that class to an specific isolated element in the theme?

enter image description here

I have tried but not seen where it documents what this data value is returned in? How can I reference this optional piece of data?

My project uses the anchor class attribute to scroll to the section of the page.

2 Answers 2

0

You can access those classes like this:

// where 'Top' is the menu name, slug or ID. But not menu location.
$menu_items = wp_get_nav_menu_items( 'Top' );

foreach ( $menu_items as $menu_item ) {
  $menu_classes = $menu_item->classes;
  print_r( $menu_classes ); 
}
0

I ended up finding that it is the first key defined in $items->classes thus used a description walker to check if there was not an empty $items->classes[0].

! empty( $item->classes[0] )
    and $attributes .= ' class="'   . esc_attr( $item->classes[0]        ) .'"';

For those of you who wish to use this in your own project please use the code below.

class description_walker extends Walker_Nav_Menu
{
/**
 * Start the element output.
 *
 * @param  string $output Passed by reference. Used to append additional content.
 * @param  object $item   Menu item data object.
 * @param  int $depth     Depth of menu item. May be used for padding.
 * @param  array|object $args    Additional strings. Actually always an 
                                 instance of stdClass. But this is WordPress.
 * @return void
 */
function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 )
{
    $classes     = empty ( $item->classes ) ? array () : (array) $item->classes;

    $class_names = join(
        ' '
    ,   apply_filters(
            'nav_menu_css_class'
        ,   array_filter( $classes ), $item
        )
    );

    ! empty ( $class_names )
        and $class_names = ' class="'. esc_attr( $class_names ) . '"';

    $output .= "<li id='menu-item-$item->ID' $class_names>";

    $attributes  = '';

    ! empty( $item->attr_title )
        and $attributes .= ' title="'  . esc_attr( $item->attr_title ) .'"';
    ! empty( $item->target )
        and $attributes .= ' target="' . esc_attr( $item->target     ) .'"';
    ! empty( $item->xfn )
        and $attributes .= ' rel="'    . esc_attr( $item->xfn        ) .'"';
    ! empty( $item->url )
        and $attributes .= ' href="'   . esc_attr( $item->url        ) .'"';

//if the custom classes field is NOT empty dump it into the link attributes. 
    ! empty( $item->classes[0] )
        and $attributes .= ' class="'   . esc_attr( $item->classes[0]        ) .'"';

    // insert description for top level elements only
    // you may change this
    $description = ( ! empty ( $item->description ) and 0 == $depth )
        ? '<small class="nav_desc">' . esc_attr( $item->description ) . '</small>' : '';

    $title = apply_filters( 'the_title', $item->title, $item->ID );

    $item_output = $args->before
        . "<a $attributes>"
        . $args->link_before
        . $title
        . '</a> '
        . $args->link_after
        . $description
        . $args->after;

    // Since $output is called by reference we don't need to return anything.
    $output .= apply_filters(
        'walker_nav_menu_start_el'
    ,   $item_output
    ,   $item
    ,   $depth
    ,   $args
    );
}
}

Let me know if this was helpful for you!

Your Answer

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

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