0

I know this question has been asked a few times, but after a lot of research I can't seem to find the answer.

The main question is: how do I convert this HTML menu to Wordpress? I don't really care if it's static, i.e. I don't have to dynamically put in into Wordpress via the admin back-end, but it won't work if it's static, because I can't give a menu item a class to know to that it's active, since I won't know which page will be active. And I can't create a different php file for every single page on my website.

When converting it to Wordpress, I don't know how to implement the dividers...

This is the code of my menu. I also have a button to open and close it and Jquery to enable that, but I don't think that's useful right now.

 <nav id="main-menu" class="main-menu">
        <div class="main-menu-top">
            <div class="main-menu-search"><?php get_search_form(); ?></div>
            <div class="main-menu-logo"><a href="/"><img src="logo.png" alt"website title" title="website title"></div></a>
        </div>
        <div class="main-menu-panel">
            <ul>
                <li class="main-menu-item">
                    <a href="/"><span class="fas fa-home"></span>Home</a>
                </li>
                <li class="main-menu-item">
                    <a href="/"><span class="fas fa-calendar-plus"></span>Updates</a>
                </li>
                <li class="main-menu-item main-menu-item-before-divider">
                    <a href="/"><span class="fas fa-comments"></span>Live</a>
                </li>
                <li class="main-menu-item main-menu-item-divider">
                    Berichten
                </li>
                <li class="main-menu-item">
                    <a href="/"><span class="fas fa-tv"></span>Televisie</a>
                </li>
                <li class="main-menu-item main-menu-item-selected">
                    <a href="/"><span class="fas fa-film"></span>Film</a>
                </li>
                <li class="main-menu-item main-menu-item">
                    <a href="/"><span class="fas fa-headphones"></span>Radio</a>
                </li>
                <li class="main-menu-item main-menu-item-before-divider">
                    <a href="/"><span class="fas fa-plus"></span>Andere</a>
                </li>
                <li class="main-menu-item main-menu-item-divider">
                    Database
                </li>
                <li class="main-menu-item">
                    <a href="/"><span class="fas fa-tv"></span>Televisie</a>
                </li>
                <li class="main-menu-item main-menu-item">
                    <a href="/"><span class="fas fa-film"></span>Film</a>
                </li>
                <li class="main-menu-item">
                    <a href="/"><span class="fas fa-headphones"></span>Radio</a>
                </li>
            </ul>
        </div>
        <div class="main-menu-bottom">
            <div class="main-menu-bottom-social social-mail">
                <a href="mailto:myemail"><span class="fas fa-envelope"></span></a>
            </div>
            <div class="main-menu-bottom-social social-facebook">
                <a href="https://www.facebook.com/myfacebook" target="_blank"><span class="fab fa-facebook-f"></span></a>
            </div>
            <div class="main-menu-bottom-social social-twitter">
                <a href="https://www.twitter.com/mytwitter" target="_blank"><span class="fab fa-twitter"></span></a>
            </div>
        </div>
    </nav>

The menu looks like this:

How the menu looks

1 Answer 1

1

This is just another normal menu. You can use CSS class in menus to add custom CSS main-menu-item-before-divider for menu item which acts as divider in CSS class field which can be activated under Screen Options tab at the top of Menu page. You can create another custom field for font awesome classes for menus. With little modification of code form here.

<?php
/**
 * Proof of concept for how to add new fields to nav_menu_item posts in the WordPress menu editor.
 * @author Weston Ruter (@westonruter), X-Team
 */

add_action( 'init', array( 'XTeam_Nav_Menu_Item_Custom_Fields', 'setup' ) );

class XTeam_Nav_Menu_Item_Custom_Fields {
    static $options = array(
        'item_tpl' => '
            <p class="additional-menu-field-{name} description description-thin">
                <label for="edit-menu-item-{name}-{id}">
                    {label}<br>
                    <input
                        type="{input_type}"
                        id="edit-menu-item-{name}-{id}"
                        class="widefat code edit-menu-item-{name}"
                        name="menu-item-{name}[{id}]"
                        value="{value}">
                </label>
            </p>
        ',
    );

    static function setup() {
        if ( !is_admin() )
            return;

        $new_fields = apply_filters( 'xteam_nav_menu_item_additional_fields', array() );
        if ( empty($new_fields) )
            return;
        self::$options['fields'] = self::get_fields_schema( $new_fields );

        add_filter( 'wp_edit_nav_menu_walker', function () {
            return 'XTeam_Walker_Nav_Menu_Edit';
        });
        //add_filter( 'xteam_nav_menu_item_additional_fields', array( __CLASS__, '_add_fields' ), 10, 5 );
        add_action( 'save_post', array( __CLASS__, '_save_post' ), 10, 2 );
    }

    static function get_fields_schema( $new_fields ) {
        $schema = array();
        foreach( $new_fields as $name => $field) {
            if (empty($field['name'])) {
                $field['name'] = $name;
            }
            $schema[] = $field;
        }
        return $schema;
    }

    static function get_menu_item_postmeta_key($name) {
        return '_menu_item_' . $name;
    }

    /**
     * Inject the 
     * @hook {action} save_post
     */
    static function get_field( $item, $depth, $args ) {
        $new_fields = '';
        foreach( self::$options['fields'] as $field ) {
            $field['value'] = get_post_meta($item->ID, self::get_menu_item_postmeta_key($field['name']), true);
            $field['id'] = $item->ID;
            $new_fields .= str_replace(
                array_map(function($key){ return '{' . $key . '}'; }, array_keys($field)),
                array_values(array_map('esc_attr', $field)),
                self::$options['item_tpl']
            );
        }
        return $new_fields;
    }

    /**
     * Save the newly submitted fields
     * @hook {action} save_post
     */
    static function _save_post($post_id, $post) {
        if ( $post->post_type !== 'nav_menu_item' ) {
            return $post_id; // prevent weird things from happening
        }

        foreach( self::$options['fields'] as $field_schema ) {
            $form_field_name = 'menu-item-' . $field_schema['name'];
            // @todo FALSE should always be used as the default $value, otherwise we wouldn't be able to clear checkboxes
            if (isset($_POST[$form_field_name][$post_id])) {
                $key = self::get_menu_item_postmeta_key($field_schema['name']);
                $value = stripslashes($_POST[$form_field_name][$post_id]);
                update_post_meta($post_id, $key, $value);
            }
        }
    }

}

// @todo This class needs to be in it's own file so we can include id J.I.T.
// requiring the nav-menu.php file on every page load is not so wise
require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
class XTeam_Walker_Nav_Menu_Edit extends Walker_Nav_Menu_Edit {
    function start_el(&$output, $item, $depth = 0, $args = [], $id = 0) {
        $item_output = '';
        parent::start_el($item_output, $item, $depth, $args, $id);
        // Inject $new_fields before: <div class="menu-item-actions description-wide submitbox">
        if ( $new_fields = XTeam_Nav_Menu_Item_Custom_Fields::get_field( $item, $depth, $args ) ) {
            $item_output = preg_replace('/(?=<div[^>]+class="[^"]*submitbox)/', $new_fields, $item_output);
        }
        $output .= $item_output;
    }
}


// Somewhere in config...
add_filter( 'xteam_nav_menu_item_additional_fields', 'mytheme_menu_item_additional_fields' );
function mytheme_menu_item_additional_fields( $fields ) {
    $fields['fa-class'] = array(
        'name' => 'fa-class',
        'label' => __('Font Awesome Class', 'xteam'),
        'container_class' => 'fa-class',
        'input_type' => 'text',
    );

    return $fields;
}

After adding the above code you should able to see another custom field for font awesome classes where you can put fa classes as fas fa-tv Then you can use walker nav class as below.

class Custom_Walker_Nav_Primary extends Walker_Nav_menu {

    function start_lvl( &$output, $depth = 0, $args = array() ){ //ul
        $indent = str_repeat("\t",$depth);
        $submenu = ($depth > 0) ? ' sub-menu' : '';
        $output .= "\n$indent<ul class=\"dropdown-menu$submenu depth_$depth\">\n";
    }

    function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ){ //li a span

        $indent = ( $depth ) ? str_repeat("\t",$depth) : '';

        $li_attributes = '';
        $class_names = $value = '';

        $classes = empty( $item->classes ) ? array() : (array) $item->classes;
        $classes[] = 'main-menu-item'; // common class for li items
        $classes[] = ($args->walker->has_children) ? 'dropdown' : '';
        $classes[] = ($item->current || $item->current_item_ancestor) ? 'active main-menu-item-selected ' : ''; // Add selected class for current menu item
        $classes[] = 'menu-item-' . $item->ID;
        if( $depth && $args->walker->has_children ){
            $classes[] = 'dropdown-submenu';
        }

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

        $id = apply_filters('nav_menu_item_id', 'menu-item-'.$item->ID, $item, $args);
        $id = strlen( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';

        $output .= $indent . '<li' . $id . $value . $class_names . $li_attributes . '>';

        $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) . '"' : '';

        $attributes .= ( $args->walker->has_children ) ? ' class="dropdown-toggle" data-toggle="dropdown"' : '';


        $item_output = $args->before;
        $item_output .= '<a' . $attributes . '>';

        $fa_class = get_post_meta($item->ID,'_menu_item_fa-class',true) ?: false;  // Get font awesome class
        if( $fa_class ){

            $item_output .= '<span class="'.$fa_class.'"></span>'; // Add span if the fa classes exists

        }

        $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
        $item_output .= ( $depth == 0 && $args->walker->has_children ) ? ' <b class="caret"></b></a>' : '</a>';
        $item_output .= $args->after;

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

    }

}

Then you can use wp_nav_menu() to get the menu

  wp_nav_menu( array('menu' => 'Main', 'container' => '', 'items_wrap' => '<ul class="nav navbar-nav" id="mymenu">%3$s</ul>' , 'walker' => new Custom_Walker_Nav_Primary()));     // you may need to change some args as per your requirement for example "menu" => "Some menu" 
1
  • 1
    Thank you! It actually worked, with a little bit of modification.
    – Stef
    Commented May 30, 2018 at 9:10

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