Вопрос или проблема
Я пытаюсь понять, как работает класс NavWalker. Я понимаю, что у него есть 3 стандартных метода, которые необходимо реализовать: start_lvl, start_el, end_el
Насколько я понимаю, вывод страницы передается в эти 3 функции по ссылке. И каждая функция должна изменить вывод, чтобы реализовать изменения на странице.
Я понимаю, что функция start_lvl должна прикрепить открывающий тег <ul>
, а функция end_el должна прикрепить закрывающий тег </ul>
.
Затем функция start_el будет прикреплять индивидуальный тег <li>
для каждого элемента меню, и эта функция будет автоматически вызываться в цикле в зависимости от количества элементов меню.
Моя функция start_el прикрепляет к выводу таким образом:
$output = $output . "<li class="customClass1"> : ". $item->title . "</li>";
Таким образом, customClass1 создает границу вокруг элемента меню.
Тем не менее, когда я смотрю на элементы меню на моей странице, я обнаруживаю, что только первый элемент меню имеет границу вокруг него. Остальные элементы меню не имеют стиля.
Почему моя функция start_el применяется только к первому элементу меню, а не ко всем?
Вот весь мой класс, который расширяет класс NavWalker:
class WalkerMenuObject extends Walker_Nav_Menu
{
function start_lvl(&$output, $depth = 0, $args = null)
{
$output = $output . "<ul class="customULClass">";
}
function start_el(&$output, $item, $depth = 0, $args = null, $id = 0)
{
$output = $output . "<li class="customClass1"> : " . $item->title . "</li>";
}
function end_el(&$output, $item, $depth = 0, $args = null)
{
$output = $output . "</ul>";
}
}
Я предполагаю, что у вас может быть применена граница к элементу списка верхнего уровня?
На данный момент, ваша реализация не совсем корректна, она бы создала HTML вроде этого:
<ul id="menu-foo" class="menu">
<li class="customClass1"> : Lorem Ipsum</li>
</ul>
<li class="customClass1"> : Dolor Sit</li>
</ul>
<li class="customClass1"> : Amet</li>
</ul>
</ul>
Это происходит потому, что функция end_el
заканчивает текущий элемент, а не текущий уровень списка. Таким образом, вы добавляете закрывающий тег </ul>
после каждого элемента, что непреднамеренно закрывает элемент <ul>
верхнего уровня.
Вы должны удалить закрывающий </li>
из start_el
и позволить end_el
закрыть его. Вы можете полностью удалить метод end_el
, чтобы унаследованный метод от Walker_Nav_Menu
закрыл его, или вы можете закрыть его самостоятельно:
function start_el(&$output, $item, $depth = 0, $args = null, $id = 0)
{
$output = $output . "<li class="customClass1"> : " . $item->title;
}
function end_el(&$output, $item, $depth = 0, $args = null)
{
$output = $output . "</li>";
}
Любой из этих методов должен дать вам более корректную разметку HTML:
<ul id="menu-foo" class="menu">
<li class="customClass1"> : Lorem Ipsum</li>
<li class="customClass1"> : Dolor Sit</li>
<li class="customClass1"> : Amet</li>
</ul>
.
Ответ или решение
Когда вы сталкиваетесь с проблемами в коде, особенно в PHP и работающем с большим количеством функций, как в случае с классом NavWalker, всегда стоит начать с понимания теории работы и назначения конкретных методов. Рассмотрим пошагово, как именно работает процесс построения меню и почему ваша функция start_el()
применяет стиль только к первой ссылке меню.
Теория
Класс NavWalker в WordPress — это мощный инструмент для создания настраиваемой навигации. Основные методы, с которыми вам нужно иметь дело в этом классе, это:
- start_lvl — открывает новый уровень списка, занимаясь генерацией открывающего тега
<ul>
. - start_el — создает каждый отдельный элемент списка (
<li>
), куда входит ваш элемент меню. Этот метод вызывается в цикле для каждого элемента меню. - end_el — завершает каждый элемент списка, закрывая тег
<li>
. - end_lvl — завершает уровень списка, добавляя закрывающий тег
</ul>
.
Пример
Ваш код функции start_el()
выглядит так:
function start_el(&$output, $item, $depth = 0, $args = null, $id = 0) {
$output = $output . "<li class="customClass1"> : " . $item->title . "</li>";
}
Здесь вы создаете строку HTML для каждого элемента списка, присваивая каждому элементу стиль customClass1
. Однако проблема заключается не в самой функции start_el()
, а в том, как вы используете функции end_el()
и start_lvl()
.
Вот исправленный код, который должен правильно применить указанную стилизацию ко всем элементам меню:
class WalkerMenuObject extends Walker_Nav_Menu
{
function start_lvl(&$output, $depth = 0, $args = null) {
$output .= "<ul class='customULClass'>";
}
function start_el(&$output, $item, $depth = 0, $args = null, $id = 0) {
$output .= "<li class='customClass1'> : " . $item->title;
}
function end_el(&$output, $item, $depth = 0, $args = null) {
$output .= "</li>";
}
}
Применение
1. Убедитесь, что start_el()
правильно открывает <li>
.
В исправленной версии добавление содержимого происходит так: начальный тег <li>
добавляется в start_el()
, а закрывающий тег </li>
в end_el()
. Это предотвращает сбой структуры HTML, где предыдущая версия кода имела неправильный закрывающий тег, находящийся в функции end_el()
.
2. Избегайте некорректного закрытия тегов
Как показано в вашем кавычке HTML, предыдущая версия добавляла тег </ul>
внутри end_el()
, который должен закрывать только элемент </li>
. Это было семантически неправильно, так как end_el()
должен заботиться только о закрытии элемента списка (<li>
), а не уровня списка (<ul>
). Удаление этого тега помогает поддерживать правильную структуру меню.
3. Проверка и тестирование
После внесения изменений, обязательно протестируйте код в разных условиях. Обратите внимание на иерархические меню и ситуации, где существуют подуровни. Убедитесь, что структура меню HTML корректная и стили применяются ко всем уровням меню. Вы можете визуально проверить структуру через инструменты разработчика в вашем браузере.
Заключение
Ошибки кроются в деталях, и в данном случае важно иметь тщательно выстроенный код, который соблюдает все правила HTML-структуры. Следуя вышеуказанным шагам и проверив настройки вашего шаблона и верстки, вы сможете добиться нужного результата и значительно расширить свои знания о работе классов в WordPress.