Статьи

Админ меню в WordPress

На первый взгляд система администрирования в WordPress работает достаточно хорошо. Встроенные функции меню решают многие проблемы, такие как добавление и удаление пунктов меню, но вы можете узнать больше о том, как WordPress обрабатывает свои меню внутри, чтобы использовать больше контроля. Приведенный ниже пример покажет, как вы можете реализовать плагин, который позволит вам упорядочить элементы меню в нужном вам порядке, объясняя нюансы системы меню WordPress.

Как WordPress заказывает пункты меню

Чтобы лучше показать, как положение элемента меню может вызвать проблемы, давайте создадим небольшой плагин, чтобы продемонстрировать, как WordPress упорядочивает элементы меню при их добавлении.

Создайте каталог в каталоге plugins , например, <root-installation>/wp-content/plugins/adminpagearranger . Затем создайте файл с именем init.php в каталоге и используйте синтаксис дескриптора плагина WordPress для идентификации плагина в системе.

В документации WordPress рекомендуется, чтобы добавление страниц администратора осуществлялось с помощью admin_menu действий admin_menu , поэтому добавьте ее прямо под дескриптором.

Самый простой способ добавить пункт меню в панель администрирования — использовать add_menu_page() которая принимает семь аргументов:

  • текст, отображаемый в заголовке страницы
  • текст пункта меню, который используется при отображении пункта меню
  • возможность, которую вы определяете, чтобы разрешить доступ к этому пункту меню
  • идентификатор порции меню, который идентифицирует это меню от любого другого в системе
  • функция, которая отображает страницу в браузере
  • путь к значку, который используется для отображения в меню, и
  • положение, при котором новый пункт меню должен отображаться относительно других пунктов меню

Поместите следующий код в init.php :

 <?php add_action("admin_menu", "addMenu"); function addMenu() { add_menu_page("My New Menu", "My New Menu", "edit_posts", "mynewmenu", "displayPage", null, 1); } 

Код сгенерирует новую ссылку на страницу, которая находится в верхней части структуры меню, чуть выше панели инструментов:

Но рассмотрим следующую реализацию addMenu() :

 <?php function addMenu() { add_menu_page("My New Menu", "My New Menu", "edit_posts", "mynewmenu", "displayPage", null, 2); } 

Просто изменив положение с 1 на 2, замените запись на панели инструментов новым меню! Почему? Все это связано с тем, как WordPress хранит конфигурацию своего меню.

WordPress использует глобальный массив $menu для хранения конфигурации меню, и каждая клавиша в массиве представляет позицию в меню. Более высокая позиция в массиве указывает на более высокую позицию в меню. Однако WordPress заполняет этот массив при запуске значениями по умолчанию. Например:

  массив
 (
     [2] => Массив
         (
             [0] => Панель инструментов
             [1] => читать
             [2] => index.php
             [3] => 
             [4] => menu-top menu-top-first menu-icon-dashboard
             [5] => меню-панель инструментов
             [6] => div
         )

     [4] => Массив
         (
             [0] => 
             [1] => читать
             [2] => Разделитель1
             [3] => 
             [4] => разделитель wp-меню
         )

     [5] => Массив
         (
             [0] => Сообщения
             [1] => edit_posts
             [2] => edit.php
             [3] => 
             [4] => open-if-no-js menu-top menu-icon-post
             [5] => сообщения меню
             [6] => div
         )

     [10] => Массив
         (
             [0] => Медиа
             [1] => upload_files
             [2] => upload.php
             [3] => 
             [4] => menu-top menu-icon-media
             [5] => меню-медиа
             [6] => div
         )
 ...
 ) 

Каждая запись в массиве фактически является другим массивом, предоставляющим подробную информацию о каждом пункте меню. Поэтому, когда выполняется вызов для добавления пункта меню в позиции 2, он фактически заменяет то, что могло быть в позиции 2 ранее. В данном случае это информация панели управления.

Когда вы добавляете новый пункт меню, помните о позиции, которую вы указали. Также обратите внимание, что аргументы, предоставленные функции add_menu_page() , теперь используются для заполнения глобального массива.

Указание пользовательского заказа меню

Теперь, когда вы знаете, как WordPress хранит конфигурацию своего меню, вы можете использовать это для управления тем, где элементы меню появляются в массиве $menu и, таким образом, изменять порядок, в котором появляются меню. WordPress предлагает два фильтра, которые можно использовать для изменения меню: menu_order и custom_menu_order .

custom_menu_order требует custom_menu_order логического значения, которое указывает, следует ли использовать пользовательское меню. По сути, возвращаемое значение из custom_menu_order определяет, применяется menu_order фильтр menu_order .

Возвращаемое значение фильтра custom_menu_order должно возвращать массив с подробным описанием элементов меню, которые вы хотите custom_menu_order в их порядке. Вы можете использовать следующую таблицу, чтобы выбрать слагов, которые относятся к стандартным пунктам меню.

 <?php add_filter("custom_menu_order", "allowMenuStructure"); add_filter("menu_order", "loadMenuStructure"); function allowMenuStructure() { return true; } function loadMenuStructure() { return array("index.php", "tools.php"); } 

Вам не нужно указывать все слагы, которые будут отображаться при возврате массива из custom_menu_order ; WordPress автоматически заполнит оставшуюся часть меню оставшимися пунктами меню в том порядке, в котором они обычно располагаются.

Создание диспетчера пользовательских меню

Мы можем использовать фильтр custom_menu_order для заполнения меню в нужном порядке, сохраняя массив в WordPress, который будет возвращен при применении этого фильтра. Вы делаете это с помощью update_option, который либо создает, либо обновляет значение, которое вы можете вызвать позже с помощью get_option() . WordPress сохраняет данные в таблице базы данных wp_options для последующего поиска. Если опция еще не была отправлена ​​или отсутствует по какой-либо причине, вы можете создать ее на основе структуры меню по умолчанию.

Первое, что вы должны сделать, это добавить свой собственный пункт меню, чтобы вы могли управлять порядком меню. Возвращаемое значение из add_menu_page() является «суффиксом хука», который вы можете добавить к ряду хуков действий, характерных для данной страницы. Здесь нас интересует load- page_hook где page_hook следует заменить суффиксом ловушки.

Этот хук является идеальным местом для обработки отправки форм, поскольку он будет происходить только при загрузке этой страницы.

Измените addMenu() мы использовали ранее для проверки функциональности меню, следующим образом:

 <?php function addMenu() { $page = add_menu_page("Admin Manager", "Admin Manager", "manage_options", "adminmanager", "displayAdminManager", null, null); add_action("load-" . $page, "handleMenu"); } 

Этот короткий фрагмент кода обязывает нас определить еще две функции — displayAdminManager() который отвечает за отображение страницы, и handleMenu() который мы будем использовать для обработки любых изменений, которые мы вносим в порядок меню.

Однако перед их определением имеет смысл определить функцию, которая загружает структуру меню, полученную из таблицы wp_options или устанавливает значение по умолчанию. Эта функция будет использоваться в нескольких местах.

 <?php function getMenuStructure() { $structure = get_option("menustructure"); if (!$structure) { global $menu; $newMenu = array(); foreach ($menu as $menuItem) { $newMenu[] = $menuItem[2]; } return $newMenu; } else { return $structure; } } 

getMenuStructure() использует get_option() чтобы попытаться get_option() структуру меню из базы данных. Если он недоступен, он создает массив для передачи обратно. Эта функция будет использоваться для фактического заполнения новой структуры меню, а также для отображения списка пунктов меню при отображении плагина, чтобы вы могли перемещать элементы вверх и вниз по структуре.

Вы можете обнаружить, что некоторые разработчики плагинов размещают свои собственные пункты меню там, где они хотят. Иногда это может быть неудобно, поскольку вы обнаружите, что обычные пункты меню будут отделены от того места, где они должны быть. Разработчики плагинов отговорены от этого в целом, но иногда вы обнаружите, что кто-то чувствует, что их плагин важнее других, и поэтому они добавляют его в верхнюю часть системы меню. Если вы хотите обойти это и убедиться, что все остальные дополнительные пункты меню расположены ниже всего остального, вы можете изменить функцию на:

 <?php function getMenuStructure() { $structure = get_option("menustructure"); if (!$structure) { return array("index.php", "separator1", "edit.php", "upload.php", "link-manager.php", "edit.php?post_type=page", "edit-comments.php", "separator2", "themes.php", "plugins.php", "users.php", "tools.php", "options-general.php", "separator-last"); } else { return $structure; } } 

Это обеспечивает реализацию структуры меню WordPress по умолчанию, и любые другие элементы будут отображаться после нее.

Заметил, что в жестко запрограммированной структуре я также использовал разделители. Разделители должны быть однозначно обозначены словом «разделитель», за которым следует целое число, а последний должен быть обозначен как «разделитель-последний».

Итак, теперь у вас есть общая функция для получения структуры меню, и вы можете посмотреть на определение функции для отображения менеджера меню, чтобы меню можно было манипулировать. Вам нужно будет включить ссылки, чтобы при нажатии они перезагрузили страницу, на которой load- page_hook действие load- page_hook .

 <?php function displayAdminManager() { $menu = getMenuStructure(); foreach($menu as $key => $menuitem) { $uplink = "admin.php?page=adminmanager&menuitem=" . $key . "&direction=up"; $downlink = "admin.php?page=adminmanager&menuitem=" . $key . "&direction=down"; echo $menuitem . ' - <a href="' . $uplink . '">Up</a> <a href="' . $downlink . '">Down</a><br>'; } } 

Обратите внимание, что мы называем саму страницу; URL-адрес этой страницы: /admin.php?page=adminmanager . Идентификатор adminmanager — это adminmanager который был установлен при добавлении страницы с помощью add_menu_page() который был четвертым аргументом. Есть также пара аргументов, подробно описывающих направление перемещения элемента меню (т. Е. Вверх или вниз) и на какой элемент меню это повлияет.

Итак, теперь у вас есть средство, с помощью которого мы можем передавать аргументы для обработки через load- page_hook который был определен как handleMenu() . Ключом к этому является то, что мы меняем пункты меню в зависимости от направления, которое было указано, и когда это делается, вы используете update_option() для сохранения вашей новой структуры меню. Затем зритель перенаправляется обратно на «эту» страницу. Это гарантирует, что новое меню загружено и реализовано.

Также неплохо убедиться, что пункты меню не могут быть перемещены за пределы структуры, проверяя, является ли элемент меню, который нужно манипулировать, первым или последним в массиве.

 <?php function handleMenu() { if (isset($_GET["menuitem"]) && isset($_GET["direction"])) { $structure = get_option("menustructure"); $numberItems = count($structure); $lastIndex = $numberItems - 1; if (!$structure) { $menu = getMenuStructure(); } else { $menu = $structure; } // if the menu item is to be moved UP the menu if ($_GET["direction"] == "down" && $_GET["menuitem"] != $lastIndex) { // move the menu up $currentIndex = $_GET["menuitem"]; $nextIndex = $currentIndex + 1; $currentMenuItem = $menu[$currentIndex]; $nextMenuItem = $menu[$nextIndex]; $menu[$currentIndex] = $nextMenuItem; $menu[$nextIndex] = $currentMenuItem; update_option("menustructure", $menu); } //if the menu item is to be moved DOWN the menu elseif ($_GET["direction"] == "up" && $_GET["menuitem"] != 0) { //move the menu down $currentIndex = $_GET["menuitem"]; $previousIndex = $currentIndex - 1; $currentMenuItem = $menu[$currentIndex]; $previousMenuItem = $menu[$previousIndex]; $menu[$currentIndex] = $previousMenuItem; $menu[$previousIndex] = $currentMenuItem; update_option("menustructure", $menu); } wp_redirect("admin.php?page=adminmanager"); } } 

Перенаправление необходимо из-за порядка, в котором происходят действия. Действие load- page_hook происходит после фильтра custom_menu_order , поэтому обновление опции «menustructure» происходит, но вы не увидите эффекта, так как заказ меню уже загружен. Перенаправление обеспечит правильную реализацию новой структуры меню, по сути, «обновляя» страницу и жизненный цикл WordPress.

Резюме

Из этого туториала вы узнаете, как внутренние админ-меню структурированы в WordPress. Вы создали простой плагин для реализации системы, с помощью которой вы можете изменить порядок пунктов меню. Мы использовали внутренние параметры WordPress для хранения и извлечения этих данных и пользовательский фильтр, чтобы обеспечить реализацию нашего пользовательского порядка меню.

Джеймс Трю / Шаттерсток