Как разместить меню произвольного типа записи над меню "Записи" используя menu_position?
Я только что разобрался с параметром menu_position, и похоже, что меню произвольного типа записи можно разместить практически везде. За исключением позиции над меню "Записи"!
Как можно этого добиться?
Позиции стандартных пунктов меню
- 2 Консоль
- 4 Разделитель
- 5 Записи
- 10 Медиафайлы
- 15 Ссылки
- 20 Страницы
- 25 Комментарии
- 59 Разделитель
- 60 Внешний вид
- 65 Плагины
- 70 Пользователи
- 75 Инструменты
- 80 Настройки
- 99 Разделитель
Описание параметра "позиция в меню"
$position
(целое число) (необязательный) Позиция в порядке меню, на которой должен отображаться данный пункт. По умолчанию, если параметр не указан, пункт появится в нижней части структуры меню. Чем выше число, тем ниже позиция пункта в меню.ВНИМАНИЕ: если два пункта меню используют одинаковое значение позиции, один из них может быть перезаписан, и будет отображаться только один пункт! Риск конфликта можно уменьшить, используя десятичные значения вместо целых чисел, например 63.3 вместо 63.
По умолчанию: внизу структуры меню

Новый плагин JetPack размещает свою ссылку в меню сразу под ссылкой на Консоль. Это достигается установкой порядка меню в 0, путем фильтрации массива $menu_order:
function jetpack_menu_order( $menu_order ) {
$jp_menu_order = array();
foreach ( $menu_order as $index => $item ) {
if ( $item != 'jetpack' )
$jp_menu_order[] = $item;
if ( $index == 0 )
$jp_menu_order[] = 'jetpack';
}
return $jp_menu_order;
}
Из любопытства, что произойдет, если попробовать установить menu_position в 0?

Искал решение в интернете, но не нашел. Вот простой способ (например). Вот стандартный список позиций:
- 2 Консоль
- 4 Разделитель
- 5 Записи
- 10 Медиафайлы
- 15 Ссылки
- 20 Страницы
- 25 Комментарии
- 59 Разделитель
- 60 Внешний вид
- 65 Плагины
- 70 Пользователи
- 75 Инструменты
- 80 Настройки
- 99 Разделитель
Если у вас больше пунктов, вы можете узнать текущую позицию каждого элемента, выведя глобальный массив $menu:
global $menu;
print_r($menu);
Если я правильно понимаю, ничто не мешает нам переупорядочить меню как угодно:
function re_order_menu () {
// ------- Убираем элементы
$dashboard = $menu[2];
$separator1 = $menu[4];
$posts = $menu[5];
$media = $menu[10];
$links = $menu[15];
$pages = $menu[20];
$comments = $menu[25];
$separator2 = $menu[59];
$appearance = $menu[60];
$plugins = $menu[65];
$users = $menu[70];
$tools = $menu[75];
$settings = $menu[80];
$separator3 = $menu[99];
// -------- Очищаем меню
unset($menu[2]);
unset($menu[4]);
unset($menu[5]);
unset($menu[10]);
unset($menu[15]);
unset($menu[20]);
unset($menu[25]);
unset($menu[59]);
unset($menu[60]);
unset($menu[65]);
unset($menu[70]);
unset($menu[75]);
unset($menu[80]);
unset($menu[99]);
// -------- Переупорядочиваем меню по своему усмотрению
$dashboard = $menu[2];
$separator1 = $menu[4];
$posts = $menu[5];
$books = $menu[6];
/* множество моих пользовательских элементов */
$authors = $menu[7];
$requests = $menu[8];
$clients = $menu[9];
$sellers = $menu[10];
$services = $menu[11];
$schedules = $menu[12];
/* оставляем немного места после */
$media = $menu[30];
$links = $menu[31];
$pages = $menu[32];
$comments = $menu[33];
$separator2 = $menu[59];
$appearance = $menu[60];
$plugins = $menu[65];
$users = $menu[70];
$tools = $menu[75];
$settings = $menu[80];
$separator3 = $menu[99];
}
add_action('admin_menu', 're_order_menu');
У меня это работает отлично, думаю, это правильный подход, я ошибаюсь?

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

Я использовал 'menu_postion' => 0, 1, 2, 3, 4.
На самом деле не имеет значения. Если поэкспериментировать, можно легко разобраться.
Использование 'menu_position' => 1 должно разместить его ниже пункта меню "Консоль" над разделителем. Значение 0 должно разместить его выше "Консоли"

Это ошибка в WordPress. Пожалуйста, ознакомьтесь с этой темой в Trac: http://core.trac.wordpress.org/ticket/14755
Исправлено в версии 4.4...
https://developer.wordpress.org/reference/functions/add_menu_page/#notes

Вы можете использовать это:
function my_move_post () {
global $menu;
$menu[6] = $menu[5]; //перемещаем запись с позиции 5 на 6
unset($menu[5]); //освобождаем позицию 5 для дальнейшего использования!
}
add_action('admin_menu', 'my_move_post');
Теперь вы можете использовать позицию 5, чтобы добавить ваше меню выше меню "Записи".

вот в чем загвоздка всей проблемы...
WordPress 4.9.2
wp-admin/menu.php:
// Если мы используем $_wp_last_object_menu, сначала увеличиваем его.
$ptype_menu_position = is_int( $ptype_obj->menu_position ) ? $ptype_obj->menu_position : ++$_wp_last_object_menu;
ВАЖНО: должно быть целым числом и НЕ должно быть уже установлено, иначе элемент попадет в конец списка.

Для рабочего решения в WordPress 5 и ниже, измените порядок с помощью следующего кода:
add_filter('custom_menu_order', '__return_true');
add_filter('menu_order', function($menu_order) {
if (
false !== ($k1 = array_search($v1 = 'edit.php', $menu_order))
&& false !== ($k2 = array_search($v2 = 'edit.php?post_type=foo', $menu_order))
) {
array_splice($menu_order, $k1, 0, $v2);
array_splice($menu_order, $k2 + 1, 1);
}
return $menu_order;
});
Предполагается, что у вас не более одного пункта меню, претендующего на первое место.

По той же ссылке, которую вы указали, написано:
menu_position
(integer) (опционально) Позиция в порядке меню, где должен отображаться тип записи.
По умолчанию: null - по умолчанию располагается ниже пункта "Комментарии"
5 - ниже "Записи"
10 - ниже "Медиафайлы"
20 - ниже "Страницы"
60 - ниже первого разделителя
100 - ниже второго разделителя
Таким образом, если вы установите menu_position
в значение, например, 4
, то это разместит его выше пункта "Записи".
Значение -1
размещает его выше ссылки Консоль
.

Хм. Попробовал 1-3? Думаю, возможно "1" (или "0") - это Панель управления. Может быть, что-то из 2-3 сработает

0 1 2 3 Идут перед Панелью управления, а 4 - под Записями. Это действительно невозможно!

Думаю, что 4 - это разделитель прямо над "Записями", а 5 - это сами "Записи", поэтому если установить menu-position в 3, пункт будет как раз перед разделителем. При стандартной конфигурации, конечно. Когда я установил для страницы своего плагина 4, он перезаписал разделитель, но появился как раз над "Записями". Хммм...

Вы можете использовать десятичные значения (в виде строк). Например, у меня есть несколько произвольных типов записей, которые я разместил в конце меню (100001, 100002, 100003).
Затем просто добавьте этот код, чтобы переместить их выше пункта меню Записи и ниже Консоли.
function reorder_admin_menu() {
global $menu;
// Добавляем разделитель
$menu["3.1"] = array(
0 => '',
1 => 'read',
2 => 'separator_' . "anything_unique",
3 => '',
4 => 'wp-menu-separator'
);
// Я разместил свои пункты меню в самом конце (именно с этими значениями), поэтому перемещаем их выше
$menu["3.2"] = $menu[100001];
$menu["3.3"] = $menu[100002];
$menu["3.4"] = $menu[100003];
unset($menu[100001]);
unset($menu[100002]);
unset($menu[100003]);
// Перемещаем пункт меню Медиафайлы (позиция 10) в начало, в той же группе
$menu["3.5"] = $menu[10];
unset($menu[10]);
// Отладка: ksort($menu); error_log( var_export( $menu, true ) );
}
add_action( 'admin_menu', 'reorder_admin_menu', 999 );
