Прежде всего давайте я покажу вам, что имею ввиду:
В каких случаях может понадобиться данный функционал?
Допустим у себя я создал файл themes/twentyten-child/truemenu.js
и подключил его при помощи wp_enqueue_script().
function true_enqueue_menu_script() { wp_enqueue_script( 'truemenu', get_stylesheet_directory_uri() . '/truemenu.js', array('jquery'), null, false ); } add_action( 'admin_enqueue_scripts', 'true_enqueue_menu_script' );
Нам он понадобится для автоматического добавления кнопки «Изменить» каждому элементу меню.
Почему не использовать функцию each()
? Да потому что она будет работать только для существующих элементов меню. А для нас важно не только изменять существующие, но и добавлять новые пункты меню.
Сам плагин доступен по этой ссылке. А дальше уже смотрите сами — вы можете просто вставить содержимое плагина в начало файла truemenu.js
или же тоже подключить его функцией wp_enqueue_script().
Вот собственно и содержимое файла truemenu.js
. Этот код добавляем кнопку «Изменить» для каждого элемента меню на странице wp-admin/nav-menus.php
и позволяет нам по нажатию на кнопку отправлять AJAX-запросы.
/* сюда вы можете вставить код плагина Live Query */ jQuery(function($){ $(".menu-item-settings").livequery(function() { $(this).append('<a class="button button-primary true-edit-menu">Изменить</a>'); }); // если не хотите использовать Live Query plugin, тогда закомментируйте строчки сверху и раскомментируйте эти //$('.menu-item-settings').each(function(i){ // $(this).append('<a class="button button-primary true-edit-menu">Изменить</a>'); //}); $('.true-edit-menu').live('click',function(){ btn = $(this); // записываем элемент кнопки в переменную item = btn.parent(); var item_url = item.find('.edit-menu-item-url').val(); // ссылка меню var item_attrtitle = item.find('.edit-menu-item-attr-title').val(); // текст при наведении var item_title = item.find('.edit-menu-item-title').val(); // анкор ссылки var item_classes = item.find('.edit-menu-item-classes').val(); // классы CSS var item_xfn = item.find('.edit-menu-item-xfn').val(); // XFN var item_desc = item.find('.edit-menu-item-description').val(); // описание var item_target = item.find('.field-link-target').find('input').attr('checked'); // открытие в новой вкладке var item_menuid = item.find('.menu-item-data-db-id').val(); // ID элемента меню var item_parentid = item.find('.menu-item-data-parent-id').val(); // ID родительского элемента меню var item_menu = $('#menu').val(); // ID самого меню var item_pos = item.find('.menu-item-data-position').val(); // порядковый номер элемента $.ajax({ type: 'POST', url: ajaxurl, data: 'action=savemenuitem&item_url=' + item_url + '&item_attrtitle=' + item_attrtitle + '&item_title=' + item_title + '&item_classes=' + item_classes + '&item_xfn=' + item_xfn + '&item_desc=' + item_desc + '&item_target=' + item_target + '&item_menuid=' + item_menuid + '&item_parentid=' + item_parentid + '&item_menu=' + item_menu + '&item_pos=' + item_pos + '&item_max=' + $('.menu-item-settings').length, beforeSend: function(xhr){ btn.text('Сохраняю...'); }, success: function(data){ btn.text('Изменить'); } }); return false; }); });
Я использовал функцию wp_insert_post() для изменения/добавления элемента меню и wp_set_object_terms() для присвоения элемента к определенному меню. Код можете вставить в functions.php
вашей темы:
function true_saveitem_callback(){ // параметры для wp_insert_post() (да, элементы меню это оказывается типы постов) $item_args = array( 'ID' => $_POST['item_menuid'], 'post_title' => $_POST['item_title'], 'post_type' => 'nav_menu_item', 'post_status' => 'publish', //'menu_order' => $_POST['item_pos'], // Я закомментировал эту строку, потому что изменение порядка элементов не работает так, как хотелось бы 'post_content' => $_POST['item_desc'], // описание 'post_excerpt' => $_POST['item_attrtitle'] // атрибут title ); // для новых элементов важно правильно установить порядок if ( 'draft' == get_post_status( intval($_POST['item_menuid']) ) ) { $item_args['menu_order'] = $_POST['item_max']; } // insert or update the menu element $item_id = wp_insert_post( $item_args ); // присваиваем элемент меню (да, сами меню это таксономии) wp_set_object_terms( $item_id, intval($_POST['item_menu']), 'nav_menu', $append = false ); // post meta parameters $target = ($_POST['item_target'] == 'checked') ? '_blank' : ''; update_post_meta( $item_id, '_menu_item_target', $target); update_post_meta( $item_id, '_menu_item_menu_item_parent', $_POST['item_parentid']); update_post_meta( $item_id, '_menu_item_classes', $_POST['item_classes']); update_post_meta( $item_id, '_menu_item_xfn', esc_attr($_POST['item_xfn'])); update_post_meta( $item_id, '_menu_item_url', esc_attr($_POST['item_url'])); die(); } if( is_admin() ) { add_action('wp_ajax_savemenuitem', 'true_saveitem_callback'); }
Если у вас возникли вопросы по использованию кода, пожалуйста, оставляйте их в комментариях.
Чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или войдите.
Благодарю! Это просто супер-класс))!
Буду пробовать вечером.
Интересная мысль, только я даже не представляю как вы должны были намучатся с этими меню что бы придумывать такие "колёса" =)
Денёк пришлось усердно поколдовать :)
Доброй ночи.
Поставила - все отлично).
Загвоздка в обратном действии). Если удалить элемент, то требуется сохранять все меню целиком. А как удалять пункты индивидуально?
Доброе утро! Удаление не делал :)
Я правильно понимаю, что надо действовать через wp_delete_post ? Прочла у тебя, что он удаляет и пост (т.е. элемент меню), и его метаданные.
Попробовала изменить
Но вторая кнопка не появилась.
Еще вопросик про порядок элементов. Целый день рою буржунет, но так и не нашла, как в волкере отсортировать пункты меню по алфавиту. Как это было в wp_page_menu.
Да,
wp_delete_post()
.Почему не появилась вторая кнопка — не представляю, возможно кэш?
На вопрос про порядок сортировки ответил в другом комментарии)
Да, наверно, кэш. Пробовала вообще удалить скрипт с сервера, а кнопка не исчезла)).
Миш, а есть идеи как все-таки фиксировать порядок элементов? Для wp_get_nav_menu_items() нужно указывать локацию или id меню, а они у меня выводятся виджетами =(.
Ну возможно нужно переписать виджеты :)