it-swarm.com.de

Wordpress API Menü/Untermenü Reihenfolge

Ich entwickle ein untergeordnetes Thema mit Wordpress 3.4.2 und der Entwicklungsversion des Options Frameworks von David Price . Dies ist mein erstes Thema, und ich bin relativ neu in diesem Bereich, also habe ich mir den Wordpress Codex angesehen und die Registrierung von Elementen in der API ausgecheckt.

Ohne externe Dateien außerhalb meines Themas zu manipulieren, habe ich mich gefragt, ob es eine Möglichkeit gibt, die Position der Seite Themenoptionen in der Hierarchie des Menüs Darstellung zu ändern aktiviert ist, entspricht die Position nicht dem ersten Bild, sondern dem zweiten.

oldnew

Ich weiß, dass Sie entweder ein Menü (wie das Aussehen Tab, Plugins , Benutzer usw.) oder ein Untermenü ( Themen , Widgets ) erstellen können. , Menüs usw.), aber wie gehe ich vor, um ein Untermenü zu erstellen, z. B. als zweites von oben?

Soweit ich erfahre, wird irgendwo eine Bestellung aufgerufen, und danach werden weitere Seiten in der functions.php-Datei abgelegt.

In meiner functions.php Datei:

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

Vielen Dank.

11
user1752759

Hier ist ein Beispiel;

Um zunächst die Reihenfolge der Untermenüelemente anhand des Array-Schlüssels zu ermitteln, können Sie einen var_dump für die globale Variable $ submenu eingeben, der Folgendes ausgibt:

(Ich verwende das Menü "Beiträge" und das Untermenü als Beispiel.)

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

Wir können sehen, dass mein Untermenüelement mit einem Schlüssel von 17 nach den Standardelementen zum Array hinzugefügt wird.

Wenn ich zum Beispiel meinen Untermenüpunkt hinzufügen möchte, muss ich dies direkt nach dem Untermenüpunkt Alle Beiträge tun, indem ich meinen Arrayschlüssel auf 6, 7, 8 oder 9 setze (alles nach 5 und vor 10) beziehungsweise.

Das ist wie man es macht...

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

}

Ergebnis,

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

... probieren Sie es aus und lassen Sie uns wissen, wie es Ihnen geht!

Update 1:

Fügen Sie dies zu Ihrer functions.php-Datei hinzu;

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

}

Mein Update bietet eine etwas einfachere Möglichkeit, die Einstellung Ihrer Menüposition vorzunehmen. Sie müssen lediglich den Namen Ihrer Untermenüseite und die gewünschte Position innerhalb des Menüs festlegen. Wenn Sie jedoch eine Untermenüseite $location auswählen, die dem eines vorhandenen Schlüssels entspricht, überschreibt sie diesen Schlüssel mit Ihrem, sodass der Menüpunkt mit Ihrem Menüpunkt an seiner Stelle verschwindet. Inkrementieren oder dekrementieren Sie die Zahl, um Ihr Menü in diesem Fall korrekt zu ordnen. Ähnliches gilt, wenn jemand ein Plugin installiert, das denselben Menübereich betrifft und für das derselbe $location wie für Ihr Untermenüelement gilt, tritt dasselbe Problem auf. Um dies zu umgehen, bietet Kaisers Beispiel einige grundlegende Überprüfungen dafür.

Update 2:

Ich habe einen zusätzlichen Codeblock hinzugefügt, der alle vorhandenen Schlüssel im Array mit unserem gewünschten $location vergleicht. Wenn eine Übereinstimmung gefunden wird, erhöhen wir unseren $location-Wert um 1, um zu vermeiden, dass Menüelemente sich gegenseitig überschreiben. Dies ist der Code, der dafür verantwortlich ist,

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

Update 3: (Skript überarbeitet, um das Sortieren mehrerer Untermenüpunkte zu ermöglichen)

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;

}

Im obigen Beispiel können Sie mehrere Untermenüs und mehrere Elemente pro Untermenü ansteuern, indem Sie die Parameter in der Variablen $target_menu, die ein mehrdimensionales Array von Werten enthält, entsprechend festlegen.

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

Diese Überarbeitung verhindert, dass sich Untermenüelemente gegenseitig überschreiben, wenn sie dieselbe Taste (Position) haben, da sie so lange durchlaufen, bis sie eine verfügbare Taste (Position) finden, die nicht vorhanden ist.

3
userabuser

Das Admin-Menü (und seine Probleme)

Da das Admin-Menü keine Hooks und keine öffentliche API (die das Verschieben der Elemente ermöglicht) enthält, müssen Sie einige Problemumgehungen verwenden. Die folgende Antwort zeigt Ihnen, was Sie in Zukunft erwartet und wie Sie vorgehen können, solange der aktuelle Kernzustand vorliegt.

Zunächst muss ich festhalten, dass scribu an einem Admin-Menü-Patch arbeitet das die Handhabung wesentlich erleichtern soll. Die aktuelle Struktur ist ziemlich durcheinander und ich habe einen Artikel darüber geschrieben der wird bald veraltet sein. Erwarten Sie, dass WP 3.6 die Dinge vollständig ändert.

Dann gibt es auch den Punkt, dass Sie Optionsseiten nicht mehr für Themen verwenden sollten. Heutzutage gibt es dafür den "Theme Customizer" .

Das Plugin

Ich habe ein Plugin geschrieben, das dies mit der Standardseite "Theme Options" für die TwentyEleven/Ten-Optionsseite testet. Wie Sie sehen, gibt es keine echte API, die eine Position zulässt. Also müssen wir das Globale abfangen.

Kurz gesagt: Folgen Sie einfach den Kommentaren und werfen Sie einen Blick auf die Admin-Hinweise, die ich hinzugefügt habe, um Ihnen eine Debug-Ausgabe zu geben.

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

Viel Glück und hab Spaß.

2
kaiser

Benutzerdefinierte Filter

Es gibt eine andere Möglichkeit, dies zu erreichen. Frag mich nicht, warum ich nicht früher darüber nachgedacht habe. Auf jeden Fall gibt es einen Filter, der einer benutzerdefinierten Menüreihenfolge gewidmet ist. Setzen Sie es einfach auf true, um eine benutzerdefinierte Bestellung zuzulassen. Dann haben Sie einen zweiten Haken, um die Hauptmenüpunkte zu bestellen. Dort fangen wir einfach den global $submenu ab und schalten um unsere Untermenüpunkte.

enter image description here

In diesem Beispiel wird das Element Menus über das Element Widgets verschoben, um seine Funktionalität zu demonstrieren. Sie können es nach Ihren Wünschen anpassen.

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