私は Wordpress 3.4.2 と Options Frameworkの開発版 / David Price を使って子テーマを開発しています。これが私の最初のテーマで、これは比較的新しいので、 Wordpress Codex を見て、アイテムをAPIに登録することを確認しました。
私のテーマ以外の外部ファイルを改ざんすることなく、 テーマオプション ページが 外観 メニューの階層内のどこに配置されているかを再調整する方法があるかどうか疑問に思いましたが有効になっている場合、位置は最初の画像のようではなく、2番目の画像のようになります。
メニュー( 外観 タブ、 プラグイン 、 ユーザー など)またはサブメニュー( テーマ 、 ウィジェット など)を作成できることを私は知っています。 、 メニュー etc)しかし、どうやってサブメニューの設定を上から2番目にするのでしょうか。
私が集めたものから、どこかで呼び出されている注文があり、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';
}
ありがとう。
これが例です。
まず、配列キーに基づいてサブメニュー項目の順序を把握するために、$ submenuグローバル変数に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のキーで配列に追加されることがわかります。
たとえば、 All Posts サブメニュー項目の直後にサブメニュー項目を追加する場合は、配列キーを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']);
}
結果、
["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"
}
}
...試してみて、どうやって行くのか教えてください。
これをあなたの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]);
}
私の更新はあなたのメニュー位置の設定を処理するためのもう少し簡単な方法を含んでいます、あなたはあなたのサブメニューページの名前とあなたがメニューの中で欲しい位置を明記するだけでよいです。 ただし、既存のキーと同じサブメニューページ それを回避するために、カイザーの例ではそのためのいくつかの基本的なチェックを提供しています。$location
を選択した場合は、そのキーが自分のキーで上書きされるため、メニュー項目はメニュー項目の代わりに表示されなくなります。その場合は、メニューを正しく順序付けるために番号を増減します。同様に、誰かがその同じメニュー領域に影響を与え、あなたのサブメニュー項目と同じ$location
を持つプラグインをインストールすると、同じ問題が発生します。
配列内に存在するすべてのキーを目的の$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;
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 (e.g. 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オプションページのデフォルトの "Theme Options"ページでこれをテストするプラグインを書きました。お分かりのように、どんな立場を可能にする本当の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
に設定します。その後、メインメニュー項目を注文するための2番目のフックを得ました。そこではglobal $submenu
をインターセプトしてサブメニュー項目を切り替えます。
この例では、 メニュー項目 をthe ウィジェット項目 に移動して、その機能を説明します。あなたはあなたが好きなものにそれを調整することができます。
<?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;
}