Меню / меню подменю WordPress

Я разрабатываю детскую тему, используя WordPress 3.4.2 и версию разработки Framework Framework от David Price . Это моя первая тема, и я относительно новичок в этом, поэтому я просмотрел WordPress Codex и проверил регистрацию элементов в API.

Без вмешательства внешних внешних файлов за пределами моей темы мне было интересно, есть ли способ переустановки, где страница параметров параметров находится в иерархии меню « Внешний вид» – поэтому, когда моя тема активирована, позиция не похожа первое изображение, но второе.

старыйновый

Я знаю, что вы можете создать либо меню (например, вкладку « Внешний вид », « Плагины» , « Пользователи» и т. Д.), Либо подменюТемы» , « Виджеты» , « Меню» и т. Д.), Но как мне настроить настройку подменю «say», «second» от верхней?

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

В моем файле functions.php:

 // Add our "Theme Options" page to the WordPress API admin menu. if ( !function_exists( 'optionsframework_init' ) ) { define( 'OPTIONS_FRAMEWORK_DIRECTORY', get_template_directory_uri() . '/inc/' ); require_once dirname( __FILE__ ) . '/inc/options-framework.php'; } 

Благодарю.

Solutions Collecting From Web of "Меню / меню подменю WordPress"

Вот пример;

Сначала, чтобы выяснить порядок пунктов подменю на основе его ключа массива, вы можете сделать var_dump в глобальной переменной подменю $, которая выведет следующее;

(В качестве примера я использую меню сообщений и подменю)

  //shortened for brevity.... ["edit.php"]=> array(6) { [5]=> array(3) { [0]=> string(9) "All Posts" [1]=> string(10) "edit_posts" [2]=> string(8) "edit.php" } [10]=> array(3) { [0]=> string(7) "Add New" [1]=> string(10) "edit_posts" [2]=> string(12) "post-new.php" } [15]=> array(3) { [0]=> string(10) "Categories" [1]=> string(17) "manage_categories" [2]=> string(31) "edit-tags.php?taxonomy=category" } [17]=> array(3) { [0]=> string(14) "Sub Menu Title" [1]=> string(10) "edit_posts" [2]=> string(17) "sub_menu_page.php" } } 

Мы видим, что мой элемент подменю добавляется в массив с ключом из 17 после элементов по умолчанию.

Если, например, я хочу добавить свой элемент подменю, сразу после элемента подменю « Все сообщения» мне нужно сделать это, установив мой ключ массива на 6, 7, 8 или 9 (все после 5 и до 10 соответственно.

Вот как вы это делаете …

 function change_submenu_order() { global $menu; global $submenu; //set our new key $new_key['edit.php'][6] = $submenu['edit.php'][17]; //unset the old key unset($submenu['edit.php'][17]); //get our new key back into the array $submenu['edit.php'][6] = $new_key['edit.php'][6]; //sort the array - important! If you don't the key will be appended //to the end of $submenu['edit.php'] array. We don't want that, we //our keys to be in descending order ksort($submenu['edit.php']); } с function change_submenu_order() { global $menu; global $submenu; //set our new key $new_key['edit.php'][6] = $submenu['edit.php'][17]; //unset the old key unset($submenu['edit.php'][17]); //get our new key back into the array $submenu['edit.php'][6] = $new_key['edit.php'][6]; //sort the array - important! If you don't the key will be appended //to the end of $submenu['edit.php'] array. We don't want that, we //our keys to be in descending order ksort($submenu['edit.php']); } 

Результат,

  ["edit.php"]=> array(6) { [5]=> array(3) { [0]=> string(9) "All Posts" [1]=> string(10) "edit_posts" [2]=> string(8) "edit.php" } [6]=> array(3) { [0]=> string(14) "Sub Menu Title" [1]=> string(10) "edit_posts" [2]=> string(17) "sub_menu_page.php" } [10]=> array(3) { [0]=> string(7) "Add New" [1]=> string(10) "edit_posts" [2]=> string(12) "post-new.php" } [15]=> array(3) { [0]=> string(10) "Categories" [1]=> string(17) "manage_categories" [2]=> string(31) "edit-tags.php?taxonomy=category" } } 

… дайте ему попробовать и сообщите нам, как вы идете!

Обновление 1:

Добавьте это в свой файл functions.php;

 function change_post_menu_label() { global $menu; global $submenu; $my_menu = 'example_page'; //set submenu page via its ID $location = 1; //set the position (1 = first item etc) $target_menu = 'edit.php'; //the menu we are adding our item to /* ----- do not edit below this line ----- */ //check if our desired location is already used by another submenu item //if TRUE add 1 to our value so menu items don't clash and override each other $existing_key = array_keys( $submenu[$target_menu] ); if ($existing_key = $location) $location = $location + 1; $key = false; foreach ( $submenu[$target_menu] as $index => $values ){ $key = array_search( $my_menu, $values ); if ( false !== $key ){ $key = $index; break; } } $new['edit.php'][$location] = $submenu[$target_menu][$key]; unset($submenu[$target_menu][$key]); $submenu[$target_menu][$location] = $new[$target_menu][$location]; ksort($submenu[$target_menu]); } с function change_post_menu_label() { global $menu; global $submenu; $my_menu = 'example_page'; //set submenu page via its ID $location = 1; //set the position (1 = first item etc) $target_menu = 'edit.php'; //the menu we are adding our item to /* ----- do not edit below this line ----- */ //check if our desired location is already used by another submenu item //if TRUE add 1 to our value so menu items don't clash and override each other $existing_key = array_keys( $submenu[$target_menu] ); if ($existing_key = $location) $location = $location + 1; $key = false; foreach ( $submenu[$target_menu] as $index => $values ){ $key = array_search( $my_menu, $values ); if ( false !== $key ){ $key = $index; break; } } $new['edit.php'][$location] = $submenu[$target_menu][$key]; unset($submenu[$target_menu][$key]); $submenu[$target_menu][$location] = $new[$target_menu][$location]; ksort($submenu[$target_menu]); } 

Мое обновление включает в себя несколько более простой способ справиться с настройкой положения вашего меню, вам нужно указать только название своей подменю и позицию, которую вы хотите в меню. Однако, если вы выберете страницу подменю $location равную $location существующего ключа, она переопределит этот ключ с вашим, поэтому пункт меню исчезнет с вашим пунктом меню на своем месте. Увеличьте или уменьшите число, чтобы правильно упорядочить свое меню, если это так. Аналогично, если кто-то устанавливает плагин, который воздействует на ту же область меню и для которой имеет то же $location что и ваш подменю, тогда будет возникать одна и та же проблема. Чтобы обойти это, пример Кайзера предоставляет некоторую базовую проверку для этого.

Обновление 2:

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

  //excerpted snippet only for example purposes (found in original code above) $existing_key = array_keys( $submenu[$target_menu] ); if ($existing_key = $location) $location = $location + 1; 

Обновление 3: (сценарий переработан, чтобы разрешить сортировку нескольких элементов подменю)

 add_action('admin_init', 'move_theme_options_label', 999); function move_theme_options_label() { global $menu; global $submenu; $target_menu = array( 'themes.php' => array( array('id' => 'optionsframework', 'pos' => 2), array('id' => 'bp-tpack-options', 'pos' => 4), array('id' => 'multiple_sidebars', 'pos' => 3), ) ); $key = false; foreach ( $target_menu as $menus => $atts ){ foreach ($atts as $att){ foreach ($submenu[$menus] as $index => $value){ $current = $index; if(array_search( $att['id'], $value)){ $key = $current; } while (array_key_exists($att['pos'], $submenu[$menus])) $att['pos'] = $att['pos'] + 1; if ( false !== $key ){ if (array_key_exists($key, $submenu[$menus])){ $new[$menus][$key] = $submenu[$menus][$key]; unset($submenu[$menus][$key]); $submenu[$menus][$att['pos']] = $new[$menus][$key]; } } } } } ksort($submenu[$menus]); return $submenu; } с add_action('admin_init', 'move_theme_options_label', 999); function move_theme_options_label() { global $menu; global $submenu; $target_menu = array( 'themes.php' => array( array('id' => 'optionsframework', 'pos' => 2), array('id' => 'bp-tpack-options', 'pos' => 4), array('id' => 'multiple_sidebars', 'pos' => 3), ) ); $key = false; foreach ( $target_menu as $menus => $atts ){ foreach ($atts as $att){ foreach ($submenu[$menus] as $index => $value){ $current = $index; if(array_search( $att['id'], $value)){ $key = $current; } while (array_key_exists($att['pos'], $submenu[$menus])) $att['pos'] = $att['pos'] + 1; if ( false !== $key ){ if (array_key_exists($key, $submenu[$menus])){ $new[$menus][$key] = $submenu[$menus][$key]; unset($submenu[$menus][$key]); $submenu[$menus][$att['pos']] = $new[$menus][$key]; } } } } } ksort($submenu[$menus]); return $submenu; } 

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

 $target_menu = array( //menu to target (eg appearance menu) 'themes.php' => array( //id of menu item you want to target followed by the position you want in sub menu array('id' => 'optionsframework', 'pos' => 2), //id of menu item you want to target followed by the position you want in sub menu array('id' => 'bp-tpack-options', 'pos' => 3), //id of menu item you want to target followed by the position you want in sub menu array('id' => 'multiple_sidebars', 'pos' => 4), ) //etc.... ); 

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

Меню администратора (и его проблемы)

Поскольку в меню администратора серьезно отсутствуют какие-либо перехватчики и открытый API (которые позволяют перемещать элементы), вы должны использовать некоторые обходные пути. Следующий ответ показывает вам, что ждет вас в будущем и как вы можете работать, пока у нас есть текущее состояние ядра.

Во-первых, я должен отметить, что scribu работает над патчем меню администратора, что должно сделать обработку намного проще. Текущая структура довольно запутана, и я написал статью об этом , которая скоро будет устаревшей. Ожидайте, что WP 3.6 полностью изменит ситуацию.

Тогда есть и то, что вам больше не следует использовать страницы с параметрами для тем. Для этого есть – в настоящее время – « Настройщик тем».

Плагин

Я написал плагин, который проверяет это на странице «Параметры темы» по умолчанию для страницы параметров TwentyEleven / Ten. Как вы можете видеть, нет никакого реального API, который допускает любую позицию. Поэтому мы должны перехватить глобальное.

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

 <?php /** Plugin Name: (#70916) Move Submenu item */ add_action( 'plugins_loaded', array( 'wpse70916_admin_submenu_items', 'init' ) ); class wpse70916_admin_submenu_items { protected static $instance; public $msg; public static function init() { is_null( self :: $instance ) AND self :: $instance = new self; return self :: $instance; } public function __construct() { add_action( 'admin_notices', array( $this, 'add_msg' ) ); add_filter( 'parent_file', array( $this, 'move_submenu_items' ) ); } public function move_submenu_items( $parent_file ) { global $submenu; $parent = $submenu['themes.php']; $search_for = 'theme_options'; // Find current position $found = false; foreach ( $parent as $pos => $item ) { $found = array_search( $search_for, $item ); if ( false !== $found ) { $found = $pos; break; } } // DEBUG: Tell if we didn't find it. if ( empty( $found ) ) return $this->msg = 'That search did not work out...'; // Now we need to determine the first and second item position $temp = array_keys( $parent ); $first_item = array_shift( $temp ); $second_item = array_shift( $temp ); // DEBUG: Check if it the item fits between the first two items: $distance = ( $second_item - $first_item ); if ( 1 >= $distance ) return $this->msg = 'We do not have enough space for your item'; // Temporary container for our item data $target_data = $parent[ $found ]; // Now we can savely remove the current options page if ( false === remove_submenu_page( 'themes.php', $search_for ) ) return $this->msg = 'Failed to remove the item'; // Shuffle items (insert options page) $submenu['themes.php'][ $first_item + 1 ] = $target_data; // Need to resort the items by their index/key ksort( $submenu['themes.php'] ); } // DEBUG Messages public function add_msg() { return print sprintf( '<div class="update-nag">%s</div>' ,$this->msg ); } } // END Class wpse70916_admin_submenu_items 

Удачи и приятного времяпровождения.

Пользовательские фильтры

Есть еще одна возможность достичь этого. Не спрашивайте меня, почему я не думал об этом раньше. Во всяком случае, есть фильтр, посвященный пользовательскому меню. Просто установите для него значение true чтобы разрешить заказ. Затем вы получите второй крючок для заказа пунктов главного меню. Там мы просто перехватываем global $submenu и переключаем наши пункты подменю.

введите описание изображения здесь

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

 <?php defined( 'ABSPATH' ) OR exit; /** * Plugin Name: (#70916) Custom Menu Order * Description: Changes the menu order of a submenu item. */ // Allow a custom order add_filter( 'custom_menu_order', '__return_true' ); add_filter( 'menu_order', 'wpse70916_custom_submenu_order' ); function wpse70916_custom_submenu_order( $menu ) { // Get the original position/index $old_index = 10; // Define a new position/index $new_index = 6; // We directly interact with the global $submenu = &$GLOBALS['submenu']; // Assign our item at the new position/index $submenu['themes.php'][ $new_index ] = $submenu['themes.php'][ $old_index ]; // Get rid of the old item unset( $submenu['themes.php'][ $old_index ] ); // Restore the order ksort( $submenu['themes.php'] ); return $menu; }