В WordPress 3 появилась наконец возможность создавать полноценные меню прямо из админки. Теперь можно менять порядок пунктов, делать сколько угодно уровней вложенности, добавлять не только страницы и посты, но и категории и постоянные ссылки. Интерфейс редактирования меню достаточно прост и удобен чтобы в нем мог разобраться любой пользователь вордпресса.

Но как быть если разработчику нужно изменить вывод HTML кода меню? И самый главный вопрос — как сделать так, чтобы текущий пункт меню не был ссылкой? Ведь согласно спецификации HTML и здравому смыслу, страница не может ссылаться сама на себя.

Для этого разработчики WordPress предусмотрели достаточно гибкую систему управления меню. Я не буду расписывать все подробности и аргументы которые можно использовать, а расскажу про создание собственной walker-функции.

В functions.php создаем новый класс, который будет расширять существующий Walker_Nav_Menu:

class mainMenuWalker extends Walker_Nav_Menu { ... }

У Walker_Nav_Menu есть свойство start_el которое отвечает за построение элемента меню. Его-то мы и будем менять:

class mainMenuWalker extends Walker_Nav_Menu {
  function start_el(&$output, $item, $depth, $args) {
    // назначаем классы li-элементу и выводим его
    $class_names = join( ' ', $item->classes );
    $class_names = ' class="' .esc_attr( $class_names ). '"';
    $output.= '<li id="menu-item-' . $item->ID . '"' .$class_names. '>';

    // назначаем атрибуты a-элементу
    $attributes.= !empty( $item->url ) ? ' href="' .esc_attr($item->url). '"' : '';
    $item_output = $args->before;

    // проверяем, на какой странице мы находимся
    $current_url = (is_ssl()?'https://':'http://').$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
    $item_url = esc_attr( $item->url );
    if ( $item_url != $current_url ) $item_output.= '<a'. $attributes .'>'.$item->title.'</a>';
    else $item_output.= $item->title;

    // заканчиваем вывод элемента
    $item_output.= $args->after;
    $output.= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
  }
}

Для того чтобы наш волкер заработал, нужно создать новый объект класса mainMenuWalker и привязать его к меню (например, в файле header.php):

$walker = new mainMenuWalker ();
wp_nav_menu ( array ( 'walker' => $walker ) );

Вот и все. Теперь в пункте меню текущей страницы нет ссылки (почему-то на западе часто игнорируют это). С помощью волкера можно добавить или удалить дополнительные элементы, классы и атрибуты в меню, но это уже другая история.

Полезные ссылки по теме