Change list item content in menu navigation to add a child element with specific class

Found the answer.

It might not be the best way to do it but it is working for now.

I was looking on using a filter when the solution seems to be using a custom walker.

class edited_menu_walker extends Walker_Nav_Menu {
    function start_el(&$output, $item, $depth, $args) {
        global $wp_query;
        $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

        $class_names = $value="";

        $classes = empty( $item->classes ) ? array() : (array) $item->classes;

        $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
        $class_names=" class="". esc_attr( $class_names ) . '"';

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

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

        //Store the span in a variable
        $prepend = '<span>';

        //Check the title of the item, deduct the class name needed for FontAwesome
        if ($item->title == 'Design') {
            $theIcoName="fa-pencil";
        } else if ($item->title == 'Frontend') {
            $theIcoName="fa-desktop";
        } else if ($item->title == 'Applications') {
            $theIcoName="fa-code";
        } else if ($item->title == 'Blog') {
            $theIcoName="fa-user";
        } else {
            $theIcoName="fa-question";
        }

        //Create the FontAwesome ready <i> element
        $ico = '<i class="fa '.$theIcoName.'"></i>';

        //Close the span and add the calculated icon
        $append = '</span>'.$ico;

        if($depth != 0) {
            $ico = $append = $prepend = "";
        }

        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before .$prepend.apply_filters( 'the_title', $item->title, $item->ID ).$append; //add prepend to open the span storing the title, append to close this span and add the FontAwesome icon in an <i> element
        $item_output .= $args->link_after;
        $item_output .= '</a>';
        $item_output .= $args->after;

        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    }
}

You have to add this code in your function.php file.

The first half of the code is the “original wordpress walker”. On the second half, where the code is a bit commented, I did some “cooking”.

To store the text (item title) of the menu item, I create a variable ‘$prepend’ opening the span element.

After that, I wrote some conditions that will determine, based on the title of the item, what should be the class of the ” element used to display the icon from FontAwesome.

If no title is found in the list, a question mark will be displayed by default with the class ‘fa-question’. That’s my “safety net” to notice that something went wront in my template and that I have to go modify my code for an eventual new icon/menu-item.

When, this deduction is made, we create the ‘$append’ variable that will be closing the ” but also adding right after it the + next to fa, the correct class.

We finally construct the output at the end with ‘$item_output=” between “‘.

I hope it is clear enough.. If someone got a better solution, feel free to share.