Wordpress API Menüsü / Alt menü Sırası


11

Ben kullanarak bir çocuk tema geliştiriyorum Wordpress 3.4.2 ve geliştirme sürümünü Seçenekler Framework tarafından David Price . Bu benim ilk temam ve bu konuda nispeten yeniyim, bu yüzden Wordpress Codex'a bir göz attım ve öğeleri API'ye kaydettirdim.

Temamın dışındaki herhangi bir harici dosyayı kurcalamadan, Tema Seçenekleri sayfasının Görünüm menüsü hiyerarşisinde nerede yeniden düzenlenebileceğinin bir yolu olup olmadığını merak ediyordum - bu yüzden temam etkinleştirildiğinde konum böyle değil ilk görüntü ama ikincisi gibi.

eskiyeni

Bir menü ( Görünüm sekmesi, Eklentiler , Kullanıcılar vb.) Veya bir alt menü ( Temalar , Widget'lar , Menüler vb.) Oluşturabileceğinizi biliyorum , ancak bir alt menü diyelim nasıl ayarlayabilirim, ikinci Üstten?

Topladığım şeyden, bir yerde bir emir var ve functions.phpdosyadaki diğer ek sayfalar bunlardan sonra mı yerleştiriliyor?

Benim fonksiyonları.php dosyasında:

// 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';
}

Teşekkürler.


Güncellenmiş işlevi denediniz mi?
Adam

Bana geri döndüğün için teşekkürler @userabuser. Güncellenmiş komut dosyanızı kopyalayıp yapıştırdım ve öğeleri başkalarını geçersiz kılmadan listede yukarı ve aşağı taşıyoruz ... Ancak, yeni güncellemeyle, Widgetlar menüsünde hala birkaç hata alıyorum . Warning: Invalid argument supplied for foreach() in /wp-content/themes/mythemename/functions.php on line 1444 Satır 1444: foreach ($submenu[$menus] as $index => $value){ ve Warning: ksort() expects parameter 1 to be array, null given in /wp-content/themes/mythemename/functions.php on line 1468 Satır 1468: ksort($submenu[$menus]);
user1752759

Eğer buna bir göz atabilirseniz, bu harika olurdu.
user1752759

Yanıtlar:


3

İşte bir örnek;

İlk olarak, dizi anahtarına dayalı olarak alt menü öğelerinin sırasını bulmak var_dumpiçin, $ submenu global değişkeninde aşağıdakileri çıkaracak bir şey yapabilirsiniz ;

(Yayınlar menüsünü ve alt menüyü örnek olarak kullanıyorum)

  //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"
    }
  }

Alt menü öğemin, varsayılan öğelerden sonra 17 tuşuyla diziye eklendiğini görebiliriz.

Örneğin, alt menü öğemi eklemek istiyorsam, Tüm Mesajlar alt menü öğesinden hemen sonra, dizi anahtarımı 6, 7, 8 veya 9'a (sırasıyla 5 ve 10'dan önce bir şey) ayarlayarak yapmam gerekir.

İşte böyle yapıyorsun ...

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']);

}

Sonuç,

  ["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"
    }
  }

... bir deneyin ve nasıl gittiğinizi bize bildirin!

Güncelleme 1:

Bunu function.php dosyanıza ekleyin;

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]);

}

Güncellemem, menü konumunuzun ayarını işlemek için biraz daha kolay bir yol içerir, yalnızca alt menü sayfanızın adını ve menü içinde istediğiniz konumu belirtmeniz gerekir. Bununla birlikte $location, mevcut bir anahtarınkine eşit bir alt menü sayfası seçerseniz , bu tuşu kendinizle geçersiz kılar, böylece menü öğesi yerine menü öğeniz kaybolur. Durum buysa, menünüzü doğru şekilde sıralamak için sayıyı artırın veya azaltın. Benzer şekilde, birisi aynı menü alanını etkileyen ve $locationalt menü öğenizle aynı olan bir eklenti yüklerse aynı sorun ortaya çıkar. Bunu atlatmak için, Kaiser örneği bunun için bazı temel kontroller sağlar.

Güncelleme 2:

Dizideki mevcut tüm anahtarları istediğimiz gibi kontrol eden ek bir kod bloğu ekledim $locationve bir eşleşme bulunursa, menü öğelerinin birbirini geçersiz kılmasını önlemek için $locationdeğerimizi artıracağız 1. Bundan sorumlu olan kod budur,

   //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;

Güncelleme 3: (birden fazla alt menü öğesinin sıralanmasına izin vermek için kod revize edildi)

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;

}

Yukarıdaki örnekte, parametreleri $target_menuçok boyutlu bir değer dizisini tutan değişken içinde uygun şekilde ayarlayarak, alt menü başına birden çok alt menüyü ve birden çok öğeyi hedefleyebilirsiniz .

$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....
);

Bu revizyon, aynı tuşa (konuma) sahipse alt menü öğelerinin birbirlerinin üzerine yazmasını önleyecektir, çünkü mevcut olmayan bir anahtar (konum) bulana kadar dolaşacaktır.


Hızlı yanıt verdiğiniz için teşekkürler userabuser, ama tüm bunlar için oldukça yeniyim, bu yüzden lütfen sadece bana katlanın. Komut dosyanızı / kodunuzu nasıl uygulayacağınızdan ve nasıl yazıldığından dolayı hangi dosyaya yerleştirilmesi gerektiğinden tam olarak emin değilim - lütfen ayrıntılı olarak belirtin. Bu örnek olsa çalışıyor ve gerekli sayıyı çıkarıyorsa ... kullanıcı daha sonra bir eklenti yükleyecekse, içinde birkaç alt düzey (e-ticaret çözümü gibi) olan ek bir üst düzey menü oluşturduysa, bu dizi anahtarı ve fren etkisi ne yapmak için ayarlanmış?
user1752759

1
@ Çubuk Menü öğelerinin birbirini geçersiz kıldığı durumlardan kaçınmaya yardımcı olacak hafif bir ayar yapıldı.
Adam

@ user1752759 Bunun yukarıdakilerle ne ilgisi var? Yukarıdaki yorumunuzda belirttiğiniz function.php dosyasının tam yolu nedir? Bu dosyadaki kod nedir? Son konuşmada bu senin için çalıştı. Benim için de işe yarıyor. Bu yüzden, başka bir şeyin kodunuzda bir bayan olabileceğinden şüpheleniyorum, son kez kodun iki parçacığını çoğalttığınızı ve işlevinizin etrafında doğru parantezlere sahip olmadığınızı doğru hatırlıyorsam.
Adam

Bana geri döndüğün için teşekkürler @userabuser. Güncellenmiş komut dosyanızı kopyalayıp yapıştırdım ve öğeleri başkalarını geçersiz kılmadan listede yukarı ve aşağı taşıyoruz ... Ancak, yeni güncellemeyle, Widgetlar menüsünde hala birkaç hata alıyorum. Warning: Invalid argument supplied for foreach() in /wp-content/themes/mythemename/functions.php on line 1444 Satır 1444: foreach ($submenu[$menus] as $index => $value){ ve Warning: ksort() expects parameter 1 to be array, null given in /wp-content/themes/mythemename/functions.php on line 1468 Satır 1468: ksort($submenu[$menus]);
user1752759

Eğer buna bir göz atabilirseniz, bu harika olurdu.
kullanıcı1752759

2

Yönetici menüsü (ve sorunları)

Yönetici menüsünde herhangi bir kanca ve genel API (öğelerin taşınmasına izin veren) bulunmadığından, bazı geçici çözümler kullanmanız gerekir. Aşağıdaki cevap, gelecekte sizi nelerin beklediğini ve şu anki çekirdek durumuna sahip olduğumuz sürece nasıl çalışabileceğinizi göstermektedir.

İlk olarak, scribu'nun işlemeyi daha kolay hale getirmesi gereken bir yönetici menüsü yaması üzerinde çalıştığını belirtmeliyim. Mevcut yapı oldukça berbat ve yakında modası geçecek bir makale yazdım . WP 3.6'nın işleri tamamen değiştirmesini bekleyin.

Ardından, temalar için artık Seçenekler sayfalarını kullanmamanız gerektiği de var. Bunun için - günümüzde - »Tema Özelleştirici« var.

Eklenti

Bunu TwentyEleven / Ten seçenekleri sayfası için varsayılan "Tema Seçenekleri" sayfasıyla test eden bir eklenti yazdım. Gördüğünüz gibi, herhangi bir pozisyona izin veren gerçek bir API yok. Bu yüzden küresel olanı kesmeliyiz.

Kısaca: Sadece yorumları takip edin ve size bazı hata ayıklama çıktısı vermek için eklediğim yönetici bildirimlerine bir göz atın.

<?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

İyi şanslar ve iyi eğlenceler.


2

Özel filtreler

Bunu başarmak için başka bir olasılık daha var. Bana neden daha önce düşünmediğimi sorma. Her neyse, özel menü sırasına adanmış bir filtre var. trueÖzel bir siparişe izin vermek için ayarlamanız yeterlidir . Sonra ana menü öğeleri sipariş için ikinci bir kanca var. Orada sadece global $submenualt menü öğelerini durdurup değiştiriyoruz.

resim açıklamasını buraya girin

Bu örnek hamle Menüler öğeyi yukarıda Widget'lar öğesine işlevselliğini göstermek için. İstediğiniz gibi ayarlayabilirsiniz.

<?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;
}

PHP @kaiser kullanmak söz konusu olduğunda pek emin değilim, ancak yukarıdaki betiği aynı menüde uygulamak içinfunction wpse70916_custom_submenu_order( $menu ) sadece Menü'yi değil , aynı zamanda Tema'yı da yeniden sıralamak için bir yol biliyor musunuz? Seçenekler , Widget'lar , Editör vb. Oldukça esnek hale getirir ve böylece öğeler birbirini geçersiz kılmaz? Teşekkür ederim.
user1752759 21:13

@ user1752759 Eklenti zaten bu esnekliğe sahip. Çatışma güvenliği (geçersiz kılmayı önlemek) başka bir konudur. Eyleminizi en son atayamayacağınız için bu% 100 senaryoda mümkün olmayacaktır. Her zaman daha sonra koşabilecek bir şey vardır. Her neyse: Lütfen yeni bir soru açın ve bu soruya bağlantı verin.
kaiser

teşekkür ederim ve kaiser yapacağız. sormak için çok fazla değilse, diğer öğeleri aynı şekilde yapmak için bir rehber olarak kullanabilmem gereken birden fazla öğenin nasıl yapıldığını (örn. Menü ve Widget'lar ) göstermek için lütfen yukarıdaki komut dosyasını güncelleyebilir misiniz ? PHP için oldukça yeni olmak, belki de sayılar nedeniyle doğru yaptığımı sanmıyorum. şerefe
user1752759

Lütfen yeni bir soru sorun ve bu soruna bağlantı verin. Teşekkürler.
kaiser
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.