add_menu_page() WP 1.5
Добавляет пункт (страницу) верхнего уровня в меню админ-панели (в один ряд с постами, страницами, пользователями и т.д.).
Используется для создания главного пункта меню в админ-панели и прикрепления к этому пункту функции, которая будет отвечать за страницу в админ-панели связанную с этим пунктом меню.
Если нужно добавить дочерний пункт меню, используйте add_submenu_page().
Если вы видите ошибку "You do not have sufficient permissions to access this page." при попытке зайти на страницу, это значит, что вы подключаете функцию слишком рано.
Подключать функцию нужно на хуке admin_menu.
Заметки
-
Функция проверяет права пользователя, чтобы отобразить пункт меню и открыть доступ к странице этого пункта меню.
-
Если используете API настроек для сохранения данных и нужно чтобы сохранение работало для пользователей с правами ниже администратора, вам нужно изменить разрешение через хук option_page_capability_{$option_page}, где
$option_page
должно быть равно параметру$menu_slug
.Пример, как разрешить Редакторам (Editor) сохранять данные:
add_action( 'admin_menu', 'register_my_page' ); add_filter( 'option_page_capability_'.'my_page_slug', 'my_page_capability' ); // Добавим видимость пункта меню для Редакторов function register_my_page(){ add_menu_page( 'My Page Title', 'My Page', 'edit_others_posts', 'my_page_slug', 'my_page_function', plugins_url( 'myplugin/images/icon.png' ), 6 ); } // Изменим права function my_page_capability( $capability ) { return 'edit_others_posts'; }
Хуков нет.
Возвращает
Строку. Название хука, название страницы меню.
Использование
add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position );
- $page_title(строка) (обязательный)
- Текст, который будет использован в теге <title> на странице, относящейся к пункту меню.
- $menu_title(строка) (обязательный)
- Название пункта меню в сайдбаре админ-панели.
- $capability(строка) (обязательный)
- Права пользователя (возможности), необходимые чтобы пункт меню появился в списке. Таблицу возможностей смотрите здесь.
- $menu_slug(строка) (обязательный)
Уникальное название (slug), по которому затем можно обращаться к этому меню.
Если параметр
$function
не указан, этот параметр должен равняться названию PHP файла относительно каталога плагинов, который отвечает за вывод кода страницы этого пункта меню.Можно указать произвольную ссылку (URL), куда будет вести клик пункта меню.
- $function(строка)
Название функции, которая выводит контент страницы пункта меню.
Этот необязательный параметр и если он не указан, WordPress ожидает что текущий подключаемый PHP файл генерирует код страницы админ-меню, без вызова функции. Большинство авторов плагинов предпочитают указывать этот параметр.
Два варианта установки параметра:
-
Если функция является методом класса, она вызывается по ссылке:
array( $this, 'function_name' )
или статически:
array( __CLASS__, 'function_name' ). - Во всех остальных случаях указываем название функции в виде строки.
По умолчанию: нет
-
- $icon_url(строка)
Иконка для пункта меню.
-
Если вам нужно подключить произвольную картинку, можно использовать функцию plugin_dir_url( __FILE__ ), чтобы получить УРЛ до папки файла плагина и затем дописать к нему название картинки: plugin_dir_url( __FILE__ ) .'plugin-icon.png'. Размеры иконки должны быть 20х20 пикселей или меньше.
-
С версии 3.8, WP использует специальные иконки dashicons, чтобы указать одну из этих иконок, выберите нужную в коллекции иконок и укажите в этом параметре название иконки. Например, иконка консоли называется dashicons-dashboard указываем это название.
-
С версии 3.8. можно указывать закодированную в base64 строку, которая будет содержать картинку: data:image/svg+xml;base64.... В этом случае, иконка будет указана как фон слоя.
-
Если указать 'none', то будет создан слой div картинку для которого можно затем указать в CSS стилях.
- По умолчанию, когда указана пустая строка '', используется иконка консоли из списка dashicons и будет добавлен CSS класс menu-icon-generic в слою иконки.
По умолчанию: ''
-
- $position(число)
Число определяющее позицию меню. Чем больше цифра, тем ниже будет расположен пункт меню.
Внимание! Если два пункта используют одинаковую цифру-позицию, один из пунктов меню может быть перезаписан и будет показан только один пункт из двух. Чтобы избежать конфликта, можно использовать десятичные значения, вместо целых чисел: 63.3 вместо 63. Используйте кавычки: "63.3".
По умолчанию, пункт меню будет добавлен в конец списка.
Список позиций для базовых пунктов меню:
2 Консоль 4 Разделитель 5 Посты 10 Медиа 15 Ссылки 20 Страницы 25 Комментарии 59 Разделитель 60 Внешний вид 65 Плагины 70 Пользователи 75 Инструменты 80 Настройки 99 Разделитель
По умолчанию: null (в конце списка иконок)
Примеры
#1 Пункт настройки темы
Этот пример показывает как добавить страницу настроек темы, в главное меню админ-панели WordPress.
<?php add_action('admin_menu', function(){ add_menu_page( 'Дополнительные настройки сайта', 'Пульт', 'manage_options', 'site-options', 'add_my_setting', '', 4 ); } ); // функция отвечает за вывод страницы настроек // подробнее смотрите API Настроек: http://wp-kama.ru/id_3773/api-optsiy-nastroek.html function add_my_setting(){ ?> <div class="wrap"> <h2><?php echo get_admin_page_title() ?></h2> <?php // settings_errors() не срабатывает автоматом на страницах отличных от опций if( get_current_screen()->parent_base !== 'options-general' ) settings_errors('название_опции'); ?> <form action="options.php" method="POST"> <?php settings_fields("opt_group"); // скрытые защитные поля do_settings_sections("opt_page"); // секции с настройками (опциями). submit_button(); ?> </form> </div> <?php }
#2 Добавление меню для администратора
Добавим пункт меню в админ-панель, который будет виден только администраторам:
Вариант 1 (только для плагинов):
add_action( 'admin_menu', 'register_my_custom_menu_page' ); function register_my_custom_menu_page(){ add_menu_page( 'custom menu title', 'custom menu', 'manage_options', 'myplugin/myplugin-admin.php', '', plugins_url( 'myplugin/images/icon.png' ), 6 ); }
В этом случае код страницы должен быть расположен в файле wp-content/plugins/myplugin/myplugin-admin.php:
<?php echo "Код страницы."; ?>
Вариант 2:
add_action( 'admin_menu', 'register_my_custom_menu_page' ); function register_my_custom_menu_page(){ add_menu_page( 'custom menu title', 'custom menu', 'manage_options', 'custompage', 'my_custom_menu_page', plugins_url( 'myplugin/images/icon.png' ), 6 ); } function my_custom_menu_page(){ echo "Код страницы."; }
#3 Добавление пункта меню, с проверкой что его еще нет
Допустим, что перед добавление пункта меню нужно убедится что этот пункт еще не добавлен из другого места. Для того чтобы такую проверку сделать очень быстрой, можно использовать глобальную переменную $admin_page_hooks
global $admin_page_hooks; if( isset($admin_page_hooks['идентификатор_пункта_меню']) ){ add_submenu_page( ... ); } else { add_menu_page( ..., ..., ..., 'идентификатор_пункта_меню' ); add_submenu_page( ... ); }
#4 Проверка наличия пункта меню или пункта подменю
Эта функция проверяет наличие пункта меню или пункта подменю по указанному идентификатору этого пункта.
/** * Находит указанный элемент меню или подменю админки. * * Нужно использовать после события 'admin_menu'. * * Пример использования: if( is_admin_menu_item_exists('options-general.php') ){ } * * @param string $handle Идентификатор пункта меню. Указывается в 4 параметре add_menu_page() или add_submenu_page() * @param boolean [$sub = false] Указан ID меню или подменю? * @return boolean Есть пункт меню или нет */ function is_admin_menu_item_exists( $handle, $sub = false ){ if( !is_admin() || (defined('DOING_AJAX') && DOING_AJAX) ) return false; global $menu, $submenu; $check_menu = $sub ? $submenu : $menu; if( empty($check_menu) ) return false; foreach( $check_menu as $k => $item ){ if( $sub ){ foreach( $item as $sm ){ if( $handle == $sm[2] ) return true; } } elseif( $handle == $item[2] ) return true; } return false; }
#5 пункт меню со ссылкой на редактирование поста
Допустим, нам нужно добавить в меню произвольную ссылку: /wp-admin/post.php?post=270&action=edit:
add_action( 'admin_menu', 'change_menu' ); function change_menu() { $post_id = 393; $url_edit = get_edit_post_link( $post_id ); if ( $url_edit ) { add_menu_page( '', 'Моя статья', 'edit_posts', $url_edit, '', '', 5 ); } }
Заметки
- Global. Массив.
$menu
- Global. Массив.
$admin_page_hooks
- Global. Массив.
$_registered_pages
- Global. Массив.
$_parent_pages
Список изменений
С версии 1.5.0 | Введена. |
А как вытащить тайтл или название страницы, которую указываешь в этой функции? Ну что-то типа the_title, только для этих страниц? А то надоело менять в функции add_menu_page, а потом в шаблоне самой страницы.
Тут в заметках про это: http://wp-kama.ru/function/add_submenu_page
Моё почтение
круто!
Из примера:
Что-то при передачи такого аргумента:
Ссылка получается от корня, то есть:
Я правда пробовал подключить файл темы так. Может для плагинов он как-то понимает, что надо путь переделать.
Если делаю так:
то получаю это:
В итоге сделал по старинке
Да так и есть, подправил в описании этот момент.
Вообще лучше указать все параметры, вот как ты в конце сделал, так лучше всего! Надо пример добавить в описание
П.С. Добавил еще пример, сделал его первым, там немного твоего кода
Почаще бы меня посещали умные мысли, я б чаще делился хорошим кодом
Вопрос: правильно ли на кастомной странице с настройками отправлять для сохранения данные на адрес options.php? Это по 1 примеру.
Да, почему нет... Так работает API опций...
Спасибо за интересную публикацию!
Kama не подскажите, есть ли возможность в add_menu_page() изменить получаемую страницу admin.php, например, на product.php. Заранее большое спасибо!
Сморите фильтры функции... Все делается через фильтры. Я не понял что конкретно вам надо.
Спасибо большое за ответ! Попробую изложить детальней. Я взял функцию add_menu_page() и создал страницу с циклом для получения одного поста авторизованного автора из произвольной записи.
Мне нужно, чтобы кастомная роль могла из определенной произвольной записи получать лишь один свой пост в административном меню... Кроме этого, созданная роль для редактирования своей опубликованной записи произвольного типа должна заходить через кнопку редактировать...
Вообщем смысл в том, что используя add_menu_page() я получаю в админке такой URL: wp-admin/admin.php?page=edit-package
А мне нужно чтобы URL не содержал admin.php, а что-то другое. Например, product.php. В итоге URL был бы таким:
wp-admin/product.php?page=edit-package
То есть можно как-то повлиять на функцию (с помощью фильтров или может нужно использовать какую-то другую функцию), чтобы получить желаемый URL. Спасибо!
Так admin.php это же не просто текст в URL - это файл с кучей кода, который описывает страницу админки, со всякими проверками по ролям, функциями и хуками.
Если вам нужно что-то уникальное для отдельной роли. Например, редактирование какого-то поста. То может проще сделать это во фронте? Или если у роли есть доступ в админку, стандартно через add_menu_page(), а там уже при обработке вывода, проверять права и раздавать кому что нужно. А URL путь будет стандартный. Поменять его конечно можно, но это больше проблем получите, проще придумать другое решение проблемы в рамках текущего URL и текущей среды. Как-то так мне кажется...
Очень благодарен за ваше мнение. Во фронте не пойдет. У кастомных ролей в дминке есть профиль и возможность редактировать еще два произвольных типа записи. Там все стандартно как и с post.
А вот именно в этом типе, нужно исключить выборку всех записей, но при этом вывести всего одну и дать возможность ее редактировать. Вот такая вот задача.
Буду думать. Просто до вашего поста где-то читал, что add_menu_page() имеет параметр, который позволяет задавать уникальное имя для страницы... Видимо имелся ввиду фильтр $menu_slug.
Цитирую: Или если у роли есть доступ в админку, стандартно через add_menu_page(), а там уже при обработке вывода, проверять права и раздавать кому что нужно.
Отвечаю: Именно так и сделал. Одна заминка с этим admin.php.
Не подскажите, может можно создать свою страницу, а потом каким-то образом привязать ее к административному меню? Или может еще какие-то подобные функции (add_menu_page()) есть. Большое спасибо!!!
Я так и не понял зачем нужно заменить admin.php. Сделать это будет вроде не просто...
Если нужно убрать все записи из таблицы записей и оставить одну. То это можно сделать через хук pre_get_posts
Спасибо! Изменить нужно, чтобы admin.php не попадал под условия запрета доступа. То есть, я жестко закрыл все страницы имеющие admin.php от непрошеных гостей. Вижу, что проще переписать условие... Спасибо Kama!!! Удачи!
Зацепись на хук current_screen и используй функцию get_current_screen() через нее открой все что хочешь открыть, остальное закрой. admin.php при этом не обязательно закрывать... Там смотри в сторону элементов массива base, parent_base, parent_file. Через них можно типами страницы закрыть/открыть... Да там кучу разных условий можно придумать под нужды и не трогать admin.php, так будет в разы проще...
Очень благодарен
Удачи!
Подскажите, пожалуйста, возможно ли каким-либо цивилизованным способом решить следующую проблему. У меня установлен плагин Media Library Plus. Он добавляет в боковое меню админки отдельный пункт "Медиафайлы +" сразу вслед за стандартным "Медиафайлы".
Я хочу засунуть его в подменю стандартного пункта. На текущий момент я тупо закомментировала в исходном файле плагина ненужные пункты подменю и строку
add_menu_page()
, заменив её строкойadd_submenu_page()
с нужными параметрами. Это, естественно, влечёт за собой необходимость каждый раз при обновлении плагина править исходный файл. Может быть можно оформить всё это через какой-нибудь фильтр или ещё что-нибудь в этом роде?Есть специальные плагины, которые позволяют довольно гибко управлять правым меню админки. Но можно и без плагина, конечно, к примеру, воспользоваться функцией remove_menu_page. А после удаления вставить ту строчку с submenu, которая у Вас уже готова.
Большое спасибо, всё получилось.
Доброго времени суток.
Столкнулся с необходимость проверки на существование в админке пункта меню для добавления в него подменю.
Сделал так:
...но, зная WordPress, гложат смутные сомнения что есть более кашерный путь решения задачи...
Так не правильно!
В Админке есть глоб. переменные
$admin_page_hooks
- хранит все пункты меню. Правильнее будет проверить существование меню через эту переменную. Нужно проверить существование нужного элемента массива.Вариант 1:
Вариант 2:
Вот еще другой вариант для проверки наличия подменю, на основе глоб. переменных $menu и $submenu....
от сюда: http://wordpress.stackexchange.com/questions/6311/how-to-check-if-an-admin-submenu-already-exists
Спасибо, Кама.
Добрый день, можно ли добавить второй пункт меню по типу записям, например новости со своими подменю как у записей?
В стиле ООП:
В чем суть писать самому $capability, разве можно использовать другую команду, не manage_options?
Добрый день, Кама.
Подскажите как сделать пункт меню со ссылкой на редактирование поста (
/wp-admin/post.php?post=270&action=edit
)Отредактируй на хуке
current_screen
глобальную переменную$menu
- добавь туда свой пункт. Черезprint_r()
посмотри что там и добавь по аналогии свой пункт.Да обычно, как и в других примерах:
для
$capability
ссылка на перечень прав пользователей уже не актуальна (