- Вопрос или проблема
- 1. Используя wp_get_nav_menu_items фильтр
- 2. Используя wp_nav_menu_items фильтр для добавления некоторых элементов
- 3. Используя один из вышеперечисленных фильтров для перезаписи некоторых элементов меню
- Ответ или решение
- 1. Использование фильтра wp_get_nav_menu_items
- Пример использования:
- 2. Использование фильтра wp_nav_menu_items
- Пример использования:
- 3. Перезапись элементов меню с помощью фильтров
- Пример использования:
- Заключение
Вопрос или проблема
Есть ли более простой способ добавить эту функциональность на страницу меню, вместо использования следующего кода? Другими словами, другой фильтр/хука/действие, которое позволит сделать так, чтобы мне не пришлось писать пользовательский JS для получения текущего порядка?
Чтобы прояснить, этот код в настоящее время просто добавляет новую ссылку на страницу nav-menus.php с названием “книги”, но то, что я хотел бы сделать, это отсортировать элементы в текущем меню, не прибегая к хакам, когда может быть что-то более распространенное для использования, что сохранит порядок элементов меню при их редактировании.
add_filter( 'wp_get_nav_menu_items', 'custom_nav_menu_items', 20, 2 );
/**
* Простая вспомогательная функция для создания объектов элементов меню
*
* @param $title - заголовок элемента меню
* @param $url - URL элемента меню
* @param $order - где элемент должен появиться в меню
* @param int $parent - родительский элемент
* @return \stdClass
*/
function _custom_nav_menu_item( $title, $url, $order, $parent = 0 ){
$item = new stdClass();
$item->ID = 1000000 + $order + parent;
$item->db_id = $item->ID;
$item->title = $title;
$item->url = $url;
$item->menu_order = $order;
$item->menu_item_parent = $parent;
$item->type="";
$item->object="";
$item->object_id = '';
$item->classes = array();
$item->target="";
$item->attr_title="";
$item->description = '';
$item->xfn = '';
$item->status="";
return $item;
}
function custom_nav_menu_items( $items, $menu ){
// добавляем элемент только в определенное меню
$items[] = _custom_nav_menu_item( 'Книги', get_post_type_archive_link('books'), 100 );
return $items;
}
Любое направление от кого-то с опытом в этом деле было бы замечательно, спасибо.
Всегда трудно сказать, какой способ решения некоторой проблемы является лучшим, потому что это зависит от мнений и убеждений. Но…
Есть 3 способа, которые я бы использовал (в зависимости от контекста и потребностей) для добавления такого элемента меню:
1. Используя wp_get_nav_menu_items
фильтр
Точно такой же способ, как вы делаете в своем вопросе. Единственная проблема заключается в том, что вам нужно быть осторожным и заполнить все необходимые поля объекта $item
. В противном случае это может вызвать предупреждения и уведомления.
PS. Фильтр wp_nav_menu_objects
довольно похож и также часто используется для этой цели.
2. Используя wp_nav_menu_items
фильтр для добавления некоторых элементов
Этот фильтр получает строку, содержащую HTML-код для элементов меню. Поэтому довольно легко добавить некоторый HTML-код к данному меню. Элементы, добавленные таким образом, не будут видны/редактируемы в админке wp.
Поэтому это довольно хорошая идея использовать, если вы хотите добавить несколько специальных ссылок в конкретное меню, которые должны всегда быть в начале или в конце – скажем, ссылку Входа/Выхода…
3. Используя один из вышеперечисленных фильтров для перезаписи некоторых элементов меню
Это еще одна довольно распространенная практика. Скажем, вы хотите добавить ссылку Входа/Выхода и позволить пользователю редактировать ее название и позицию. Но, конечно, вы не хотите заставлять пользователя редактировать его URL.
Таким образом, вы можете добавить некоторый заполнитель в качестве URL и затем использовать фильтр для его перезаписи. Например, вы можете добавить “Войти | Выйти” в качестве названия и “#loginouturl” в качестве URL, а затем использовать фильтры для изменения названия и URL в зависимости от текущего пользователя (если он вошел в систему или анонимный).
Каждое из этих решений имеет свои хорошие и плохие стороны. Некоторые из них лучше в некоторых случаях.
Ответ или решение
Динамическое добавление элементов в меню WordPress — это распространённая задача среди разработчиков. Вопрос о том, является ли предложенный вами метод лучшим практическим решением, требует рассмотрения разных подходов к решению этой проблемы. Ниже представлены три основных способа, которые могут быть использованы для достижения данной функциональности, с анализом их плюсов и минусов.
1. Использование фильтра wp_get_nav_menu_items
Вы используете фильтр wp_get_nav_menu_items
, который предоставляет возможность модифицировать массив элементов меню. Этот подход, как правило, является наиболее распространённым и используемым. Тем не менее, он требует внимательности к всем необходимым полям данных, которые должны быть заполнены в объекте $item
. В противном случае это может привести к предупреждениям и ошибкам, что может негативно сказаться на пользовательском опыте.
Также стоит отметить, что аналогичный фильтр wp_nav_menu_objects
может быть использован и для той же цели. Его применение может быть более предпочтительным в зависимости от конкретных требований вашего проекта.
Пример использования:
add_filter( 'wp_get_nav_menu_items', 'custom_nav_menu_items', 20, 2 );
function custom_nav_menu_items( $items, $menu ) {
$items[] = _custom_nav_menu_item( 'Books', get_post_type_archive_link('books'), 100 );
return $items;
}
2. Использование фильтра wp_nav_menu_items
Этот фильтр возвращает строку HTML-кода элементов меню. Его использование удобно, когда необходимо добавить несколько специфических ссылок, которые должны всегда быть первыми или последними — например, ссылки на вход или выход. Однако стоит учитывать, что элементы, добавленные таким образом, не будут видимыми и редактируемыми в админ-панели WordPress.
Пример использования:
add_filter( 'wp_nav_menu_items', 'add_login_logout_link', 10, 2 );
function add_login_logout_link( $items, $args ) {
$items .= '<li class="menu-item"><a href="' . wp_login_url() . '">Войти</a></li>';
return $items;
}
3. Перезапись элементов меню с помощью фильтров
Третий подход заключается в том, чтобы сначала добавить элементы с помощью одного из вышеуказанных фильтров, затем использовать дополнительный фильтр для изменения меток или URL в зависимости от состояния пользователя (вошел или нет). Это позволяет предоставить пользователю возможность редактировать метки и их положение без необходимости изменения URL.
Пример использования:
add_filter( 'wp_nav_menu_items', 'dynamic_login_logout_link', 10, 2 );
function dynamic_login_logout_link( $items, $args ) {
if ( is_user_logged_in() ) {
$items .= '<li class="menu-item"><a href="' . wp_logout_url() . '">Выйти</a></li>';
} else {
$items .= '<li class="menu-item"><a href="' . wp_login_url() . '">Войти</a></li>';
}
return $items;
}
Заключение
Каждый из предложенных методов имеет свои преимущества и недостатки. Выбор подхода зависит от ваших конкретных требований и контекста реализации. Если ваша цель заключается в том, чтобы сделать меню более интерактивным и управляемым непосредственно из панели администратора, рекомендуется использовать фильтр wp_get_nav_menu_items
. Если же вам нужно простое добавление ссылки, удобным будет wp_nav_menu_items
.
Прежде чем выбрать тот или иной подход, учтите, что поддержка существующего кода и необходимые изменения в будущем могут повлиять на ваше решение. Всегда полезно исследовать и тестировать разные варианты, чтобы понять, какой подход лучше всего соответствует вашим нуждам и стандартам разработки.