Дополнительные поля для меню WP_Nav_Menu
C версии WordPress 5.4 появились новые хуки, которые позволяют более гибко настроить меню WordPress (WP Nav Menu). В частности стало возможным легко добавлять пользовательские (дополнительные) поля в меню WordPress.
Речь идет о хуках wp_nav_menu_item_custom_fields и wp_nav_menu_item_custom_fields_customize_template. С их помощью теперь можно легко добавлять собственные произвольные поля к пунктам меню как на странице редактирования меню в админке, так и в панели Customizer.
В этой заметке мы рассмотрим использование хука wp_nav_menu_item_custom_fields для добавления собственных пользовательских полей в пункты меню. Также рассмотрим плагины, которые позволяют сделать тоже самое без написания кода.
Добавим поля в меню с помощью PHP кода
Код ниже использует два хука для создания нового поля в меню _menu_item_svg_icon:
- wp_nav_menu_item_custom_fields - позволяет вывести HTML код в админ-панели меню.
- wp_update_nav_menu_item - позволяет сохранить добавленные поля в метаполя элемента меню (напомню что элементы меню хранятся в таблице wp_posts и используют стандартные метаполя постов).
Также используется два хука, чтобы обработать вывод созданного поля. Здесь в поле храниться название файла иконки SVG. При выводе меню и немного костыльным, но простым способом добавляем плейсхолдер в базовую HTML разметку элемента и затем заменяем его на SVG картинку.
<?php
final class WP_Nav_Menu_Custom_Fields {
public static array $field_keys = [
'_menu_item_svg_icon' => [
'title' => 'SVG Icon Name',
'desc' => 'Set svg icon name (not url)',
],
'test_number_field' => [
'title' => 'Number One',
'type' => 'number',
'size' => 'thin', // thin | wide
// 'desc' => 'some text',
],
'test_number_field_two' => [
'title' => 'Number Two',
'type' => 'number',
'size' => 'thin', // thin | wide
// 'desc' => 'some text',
],
];
public static function init(): void {
if( is_admin() ){
add_action( 'wp_nav_menu_item_custom_fields', [ __CLASS__, 'add_fileds' ], 10, 2 );
add_action( 'wp_update_nav_menu_item', [ __CLASS__, 'save_fields' ], 10, 2 );
}
// front
else {
add_filter( 'walker_nav_menu_start_el', [ __CLASS__, 'nav_menu_start_el' ], 10, 2 );
add_filter( 'wp_nav_menu_args', [ __CLASS__, 'nav_menu_args' ] );
}
}
public static function add_fileds( $item_id, $item ) {
foreach( self::$field_keys as $meta_key => $data ){
$value = get_post_meta( $item_id, $meta_key, true );
$title = $data['title'];
$type = $data['type'] ?? 'text';
$size = $data['size'] ?? 'wide';
$desc = empty( $data['desc'] ) ? '' : '<span class="description">'. $data['desc'] .'</span>';
?>
<p class="field-<?= $meta_key ?> description description-<?= $size ?>">
<?= $title ?>
<br/>
<input class="widefat edit-menu-item-<?= $meta_key ?>"
type="<?= $type ?>"
name="<?= sprintf( '%s[%s]', $meta_key, $item_id ) ?>"
id="menu-item-<?= $item_id ?>"
value="<?= esc_attr( $value ) ?>"/>
<?= $desc ?>
</p>
<?php
}
}
public static function save_fields( $menu_id, $item_id ) {
foreach( self::$field_keys as $meta_key => $data ){
self::save_field( $menu_id, $item_id, $meta_key );
}
}
private static function save_field( $menu_id, $item_id, $meta_key ) {
if( ! isset( $_POST[ $meta_key ][ $item_id ] ) ){
return;
}
$val = $_POST[ $meta_key ][ $item_id ];
if( $val ){
update_post_meta( $item_id, $meta_key, sanitize_text_field( $val ) );
}
else{
delete_post_meta( $item_id, $meta_key );
}
}
public static function nav_menu_start_el( $item_output, $post ){
$svg = $post->_menu_item_svg_icon ?: '';
if( $svg ){
$svg = get_svg( $svg );
}
return str_replace( '{SVG}', $svg, $item_output );
}
public static function nav_menu_args( $args ){
if( empty( $args['link_before'] ) ){
$args['link_before'] = '{SVG}';
}
return $args;
}
}
После установки этого кода (создайте файл из этого кода и подключите его в functions.php), его нужно запустить такой строкой в файле functions.php:
WP_Nav_Menu_Custom_Fields::init();
Теперь, когда мы зайдем на страницу админ-панели "Тема > Меню (Appearance > Menus)" мы увидим там новые поля:
Получение полей
Чтобы получить поля на выводе используйте функцию get_post_meta():
$field_value = get_post_meta( $item_id, $field_key, true );
Такой код можно использовать например в методе start_el() при создании своего класса для обработки вывода меню. Или в хуках, которые меняю вывод навигационного меню.
Добавим поля в меню с помощью плагина Advanced Custom Fields (ACF)
Очень популярный и универсальный плагин Advanced Custom Fields снова демонстрирует свою гибкость, позволяя добавлять пользовательские поля в меню WordPress.
После установки и активации плагина, откройте его и нажмите на кнопку "Добавить новое", чтобы добавить поля. Выберите 'Menu Item' в правилах расположения. Следуйте инструкциям и обновите поля по мере необходимости.
После публикации поля вы можете перейти в меню WordPress из области администратора, чтобы увидеть новое поле, которое вы создали. Довольно просто!
Добавим поля в меню с помощью плагина WP Menu Custom Fields
Плагин WP Menu Custom Fields - это относительно новый плагин, который, как следует из названия, поможет вам добавить пользовательские поля в пункты вашего меню. Вы можете добавить пользовательский текст, изображение, шорткод или пользовательский HTML.
Вместо того чтобы создавать пользовательские пункты меню через специальный интерфейс плагина (как это делается с Advanced Custom Fields), WP Menu Custom Fields добавляет редактируемые параметры непосредственно в любой пункт меню в области редактирования меню администратора.
Он довольно прост в использовании и представляет собой удобный способ добавления пользовательских полей и другого содержимого в пункты меню. Документация плагина также предоставляет крючки плагина, которые вы можете использовать для дальнейшей настройки HTML-генерации каждой функции.


