वर्डप्रेस एपीआई मेनू / सबमेनू ऑर्डर


11

मैं Wordpress 3.4.2 और डेविड प्राइस द्वारा विकल्प फ्रेमवर्क के विकास संस्करण का उपयोग करके एक बाल-विषय विकसित कर रहा हूं । यह मेरा पहला विषय है और मैं इसके लिए अपेक्षाकृत नया हूं, इसलिए मैंने वर्डप्रेस कोडेक्स पर एक नज़र डाली और एपीआई में पंजीकृत वस्तुओं की जांच की।

मेरी थीम के बाहर किसी भी बाहरी फ़ाइल के साथ छेड़छाड़ किए बिना, मैं सोच रहा था कि क्या फिर से व्यवस्थित करने का कोई तरीका है जहां थीम विकल्प पृष्ठ उपस्थिति मेनू के पदानुक्रम के भीतर स्थित है - इसलिए जब मेरा विषय सक्रिय होता है, तो स्थिति जैसी नहीं होती है पहली छवि लेकिन दूसरी की तरह।

पुरानानया

मुझे पता है कि आप या तो एक मेनू बना सकते हैं (जैसे प्रकटन टैब, प्लगइन्स , उपयोगकर्ता आदि) या एक उप-मेनू ( विषय - वस्तु , विजेट , मेनू आदि), लेकिन मैं उप-मेनू सेट करने के बारे में कैसे कहूंगा, दूसरा ऊपर से?

मैं जो इकट्ठा करता हूं, उसमें कहीं न कहीं एक आदेश कहा जा रहा है और functions.phpफ़ाइल के भीतर किसी भी अन्य अतिरिक्त पृष्ठों को उनके बाद रखा जाता है?

मेरे कार्यों में। 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';
}

धन्यवाद।


क्या आपने अपडेट किए गए फ़ंक्शन को आज़माया है?
एडम

मुझे @userabuser पर वापस पाने के लिए धन्यवाद। मैंने आपकी अपडेट की गई स्क्रिप्ट को कॉपी-पेस्ट कर लिया है और यह आइटम को बिना किसी अन्य को ओवरराइड किए सूची में ऊपर और नीचे ले जाने के लिए लगता है ... हालांकि, नए अपडेट के साथ, मैं अभी भी विजेट मेनू पर कुछ त्रुटियां प्राप्त कर रहा हूं । Warning: Invalid argument supplied for foreach() in /wp-content/themes/mythemename/functions.php on line 1444 लाइन 1444: foreach ($submenu[$menus] as $index => $value){ और Warning: ksort() expects parameter 1 to be array, null given in /wp-content/themes/mythemename/functions.php on line 1468 लाइन 1468: ksort($submenu[$menus]);
user1752759

यदि आप इस पर एक नज़र डाल सकते हैं, तो यह बहुत अच्छा होगा।
user1752759

जवाबों:


3

यहाँ एक उदाहरण है;

अपनी सरणी कुंजी के आधार पर उप मेनू आइटम के क्रम का पता लगाने के लिए आप 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']);

}

परिणाम,

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

इसे अपने फंक्शन्स में जोड़ें। एफपी फाइल;

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आपके सबमेनू आइटम के समान है तो वही समस्या होगी। इसे दरकिनार करने के लिए, कैसर का उदाहरण इसके लिए कुछ बुनियादी जाँच प्रदान करता है।

अपडेट 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;

}

ऊपर दिए गए उदाहरण में आप कई उप मेनू और प्रत्येक आइटम को उप मेनू के अनुसार मापदंडों के अनुसार निर्धारित कर सकते हैं $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....
);

यह संशोधन उप मेनू आइटम को एक-दूसरे को लिखने से रोक देगा यदि उनके पास एक ही कुंजी (स्थिति) है, क्योंकि यह तब तक चक्र होगा जब तक कि यह एक उपलब्ध कुंजी (स्थिति) नहीं ढूंढता है जो मौजूद नहीं है।


त्वरित प्रतिक्रिया userabuser के लिए धन्यवाद, लेकिन मैं इस सब के लिए काफी नया हूं, इसलिए कृपया बस मेरे साथ रहें। मुझे ठीक से पता नहीं है कि ऊपर अपनी लिपि / कोड को कैसे लागू किया जाए और किस फाइल को इस वजह से रखा जाए कि इसे किस तरह लिखा जाए - कृपया विस्तृत करें। इस उदाहरण के साथ काम करना हालांकि और नंबर की आवश्यकता को आउटपुट करना ... यदि उपयोगकर्ता को बाद में उस पर एक प्लगइन स्थापित करना था, तो कुछ उप-स्तरों के साथ एक अतिरिक्त शीर्ष-स्तरीय मेनू बनाया (जैसे कि ई-कॉमर्स समाधान), क्या यह होगा सरणी कुंजी को प्रभावित करें और ऐसा करने के लिए क्या निर्धारित किया गया है?
user1752759

1
@ रब ने एक मामूली समायोजन किया जो उन परिस्थितियों से बचने में मदद करना चाहिए जहां मेनू आइटम एक-दूसरे को ओवरराइड करते हैं।
एडम

@ user1752759 उपरोक्त के साथ क्या करना है? फ़ंक्शंस.php फ़ाइल का पूरा रास्ता क्या है जो आप अपने उपरोक्त टिप्पणी में प्रदान करते हैं? उस फ़ाइल के भीतर कोड क्या है? अंतिम बातचीत में यह आपके लिए काम किया। यह मेरे लिए भी काम करता है। इसलिए मुझे संदेह है कि यहां कुछ और आपके कोड के भीतर एक मिस हो सकता है, अगर मुझे याद है कि पिछली बार आपने कोड के दो स्निपेट दोहराए थे और आपके फ़ंक्शन के आसपास सही ब्रेसिज़ नहीं थे।
एडम

मुझे @userabuser पर वापस पाने के लिए धन्यवाद। मैंने आपकी अद्यतन स्क्रिप्ट को कॉपी-पेस्ट कर दिया है और ऐसा लगता है कि आइटम को बिना किसी अन्य को ओवरराइड किए बिना सूची को ऊपर और नीचे ले जाना है ... हालांकि, नए अपडेट के साथ, मैं अभी भी विजेट मेनू पर कुछ त्रुटियां प्राप्त कर रहा हूं। Warning: Invalid argument supplied for foreach() in /wp-content/themes/mythemename/functions.php on line 1444 लाइन 1444: foreach ($submenu[$menus] as $index => $value){ और Warning: ksort() expects parameter 1 to be array, null given in /wp-content/themes/mythemename/functions.php on line 1468 लाइन 1468: ksort($submenu[$menus]);
user1752759

यदि आप इस पर एक नज़र डाल सकते हैं, तो यह बहुत अच्छा होगा।
user1752759

2

व्यवस्थापक मेनू (और इसकी समस्याएं)

जैसा कि व्यवस्थापक मेनू में गंभीरता से किसी भी हुक और एक सार्वजनिक एपीआई का अभाव है (जो आइटम को चारों ओर ले जाने की अनुमति देता है), आपको कुछ वर्कअराउंड का उपयोग करना होगा। निम्नलिखित उत्तर आपको दिखाता है कि आप भविष्य में क्या इंतजार कर रहे हैं और जब तक हमारे पास कोर की वर्तमान स्थिति है, तब तक आप कैसे काम कर सकते हैं।

पहले मुझे ध्यान देना है, कि स्क्रिबु एक व्यवस्थापक मेनू पैच पर काम कर रहा है जो कि हैंडलिंग को बहुत आसान बनाना चाहिए। वर्तमान संरचना बहुत गड़बड़ है और मैंने इसके बारे में एक लेख लिखा है जो जल्द ही पुराना हो जाएगा। पूरी तरह से चीजों को बदलने के लिए WP 3.6 की अपेक्षा करें।

फिर यह भी बिंदु है, कि अब आपको थीम के लिए विकल्प पृष्ठों का उपयोग नहीं करना चाहिए। वहाँ है - आजकल - »थीम Customizer« उसके लिए।

प्लगइन

मैंने एक प्लगइन लिखा है जो इसे TwentyEleven / Ten विकल्प पृष्ठ के लिए डिफ़ॉल्ट "थीम विकल्प" पृष्ठ के साथ परीक्षण करता है। जैसा कि आप देख सकते हैं, कोई वास्तविक एपीआई नहीं है जो किसी भी स्थिति की अनुमति देता है। इसलिए हमें वैश्विक अवरोधन करना होगा।

संक्षेप में: बस टिप्पणियों का पालन करें और व्यवस्थापक नोटिस पर एक नज़र डालें, जो मैंने आपको कुछ डिबग आउटपुट देने के लिए जोड़ा है।

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

गुड लक और मजा करें।


2

कस्टम फ़िल्टर

इसे हासिल करने की एक और संभावना है। मुझसे मत पूछिए कि मैंने इसके बारे में पहले क्यों नहीं सोचा। वैसे भी, कस्टम मेनू ऑर्डर के लिए समर्पित एक फ़िल्टर है। trueएक कस्टम ऑर्डर की अनुमति देने के लिए बस इसे सेट करें। फिर आपको मुख्य मेनू आइटम ऑर्डर करने के लिए दूसरा हुक मिला। वहाँ हम बस को रोकते हैं global $submenuऔर हमारे उप मेनू आइटम के चारों ओर स्विच करते हैं।

यहाँ छवि विवरण दर्ज करें

यह उदाहरण इसकी कार्यक्षमता प्रदर्शित करने के लिए विजेट आइटम के ऊपर मेनू आइटम को ले जाता है । आप इसे अपनी पसंद के अनुसार समायोजित कर सकते हैं।

<?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 का उपयोग करने की बात आती है, लेकिन क्या आप संभवतः स्क्रिप्ट को लागू करने का एक तरीका जानते हैं, जिसमें एक ही function wpse70916_custom_submenu_order( $menu )कहने के लिए एक से अधिक आइटम शामिल करने के लिए, न केवल मेनू , बल्कि थीम भी विकल्प , विजेट , संपादक आदि इसे काफी लचीला बनाते हैं और यह भी कि आइटम एक-दूसरे को ओवरराइड नहीं करते हैं? धन्यवाद।
user1752759

@ user1752759 प्लगइन में पहले से ही यह लचीलापन है। संघर्ष की सुरक्षा (ओवरराइडिंग से बचें) एक और मुद्दा है। यह 100% परिदृश्य में संभव नहीं होगा क्योंकि आप अपनी कार्रवाई को अंतिम रूप नहीं दे सकते। हमेशा कुछ ऐसा होता है जो बाद में चल सकता है। वैसे भी: कृपया एक नया प्रश्न खोलें और इस पर लिंक करें।
केसर

धन्यवाद और कैसर करूंगा। अगर यह पूछने के लिए बहुत अधिक नहीं है, तो क्या आप उपरोक्त स्क्रिप्ट को अपडेट करने के लिए दिखा सकते हैं कि कितने आइटम किए गए हैं (उदाहरण के लिए, मेनू और विजेट ), जिन्हें मैं अन्य वस्तुओं के समान करने के लिए एक गाइड के रूप में उपयोग करने में सक्षम होना चाहिए? PHP में काफी नया होने के कारण, मुझे नहीं लगता कि मैं इसे सही ढंग से कर रहा हूं, शायद संख्या के कारण। चीयर्स
user1752759

कृपया बस एक नया प्रश्न पूछें और इस एक से लिंक करें। धन्यवाद।
कैसर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.