Wordpress API Menu / Sous-menu Ordre

11

Je développe un thème enfant en utilisant Wordpress 3.4.2 et la version de développement du Options Framework de David Price . C’est mon premier thème et je suis relativement nouveau dans ce domaine. J’ai donc jeté un œil au Codex Wordpress et j’ai vérifié comment enregistrer des éléments dans l’API.

Sans toucher à aucun fichier externe en dehors de mon thème, je me demandais s'il était possible de réorganiser l'emplacement de la page Options de thème dans la hiérarchie de Apparence menu - donc quand mon thème est activé, la position n’est pas celle de la première image mais celle de la seconde.

Je sais que vous pouvez créer un menu (tel que l'onglet Apparence , Plugins , Utilisateurs , etc.) ou un sous-menu. ( Thèmes , Widgets , Menus , etc.), mais comment puis-je configurer un sous-menu, deuxième en partant du haut?

D'après ce que je comprends, une commande est appelée quelque part et toute autre page supplémentaire du fichier functions.php est placée après celle-ci?

Dans mon fichier 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';
}

Merci.

    
posée user1752759 30.10.2012 - 07:18

3 réponses

3

Voici un exemple;

Tout d'abord, pour déterminer l'ordre des éléments de sous-menu en fonction de sa clé de tableau, vous pouvez effectuer un var_dump sur la variable globale $ du sous-menu qui générera le résultat suivant;

(J'utilise le menu Messages et le sous-menu à titre d'exemple)

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

Nous pouvons voir que mon élément de sous-menu est ajouté au tableau avec une clé de 17 après les éléments par défaut.

Si, par exemple, je souhaite ajouter un élément de sous-menu, directement après l'élément de sous-menu Tous les messages , je dois le faire en définissant ma clé de tableau sur 6, 7, 8 ou 9 ( quoi que ce soit après 5 et avant 10 respectivement.

Voici comment vous le faites ...

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

}

Résultat,

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

... essayez-le et dites-nous comment vous allez!

Mise à jour 1:

Ajoutez ceci à votre fichier 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]);

}

Ma mise à jour comprend un moyen légèrement plus simple de gérer le paramétrage de la position de votre menu. Il vous suffit de spécifier le nom de la page de votre sous-menu et la position souhaitée dans le menu. Cependant, si vous sélectionnez une page de sous-menu $location égale à celle d'une touche existante, cette touche sera remplacée par la votre, ainsi l'élément de menu disparaîtra avec votre élément de menu à la place. Incrémentez ou décrémentez le nombre afin d’organiser correctement votre menu si tel est le cas. Semblable, si quelqu'un installe un plugin qui affecte la même zone de menu et qui a le même $location que votre élément de sous-menu, le même problème se produira. Pour contourner ce problème, l'exemple de Kaiser fournit quelques vérification de base pour cela.

Mise à jour 2:

J'ai ajouté un bloc de code supplémentaire qui vérifie toutes les clés existantes du tableau par rapport à notre $location souhaité. Si une correspondance est trouvée, nous incrémenterons notre valeur $location de 1 afin d'éviter les éléments de menu. se substituer. C’est le code responsable de cela,

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

Mise à jour 3: (script révisé pour permettre le tri de plusieurs éléments de sous-menu)

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;

}

Dans l'exemple ci-dessus, vous pouvez cibler plusieurs sous-menus et plusieurs éléments par sous-menu en définissant les paramètres en conséquence dans la variable $target_menu qui contient un tableau de valeurs multidimensionnel.

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

Cette révision empêchera les éléments de sous-menu de s’écraser s’ils ont la même clé (position), car ils seront parcourus jusqu’à trouver une clé disponible (position) inexistante.

    
réponse donnée userabuser 30.10.2012 - 13:07
2

Le menu administrateur (et ses problèmes)

Étant donné que le menu d'administration manque sérieusement de points d'ancrage et d'une API publique (qui permet de déplacer les éléments), vous devez utiliser certaines solutions de contournement. La réponse suivante vous montre ce qui vous attend dans l’avenir et comment vous pouvez le contourner tant que vous avez l’état actuel du cœur.

Je dois d’abord noter que scribu fonctionne sur un correctif de menu d’administrateur qui devrait rendre la gestion beaucoup plus facile. Plus facile. La structure actuelle est assez désordonnée et j'ai écrit un article à ce sujet qui sera bientôt obsolète . Attendez-vous à ce que WP 3.6 change complètement les choses.

Ensuite, il est également important de ne plus utiliser les pages Options pour les thèmes. De nos jours, le »Thème Customizer« pour cela.

Le plugin

J'ai écrit un plugin qui teste cela avec la page "Options du thème" par défaut de la page d'options TwentyEleven / Ten. Comme vous pouvez le constater, il n’existe pas de véritable API qui permette une position. Nous devons donc intercepter le global.

En bref: suivez les commentaires et jetez un coup d’œil aux avis de l’administrateur, que j’ai ajoutés pour vous donner un résultat de débogage.

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

Bonne chance et amusez-vous.

    
réponse donnée kaiser 30.10.2012 - 14:16
2

Filtres personnalisés

Il existe une autre possibilité pour y parvenir. Ne me demandez pas pourquoi je n'y ai pas pensé plus tôt. Quoi qu'il en soit, il existe un filtre dédié à un ordre de menu personnalisé. Il suffit de le définir sur true pour autoriser une commande personnalisée. Ensuite, vous avez un deuxième crochet pour commander les éléments du menu principal. Ici, nous interceptons simplement global $submenu et basculons autour de nos éléments de sous-menu.

  

Cet exemple déplace l'élément Menus au-dessus de l'élément Widgets pour en démontrer la fonctionnalité. Vous pouvez l’ajuster à votre guise.

<?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;
}
    
réponse donnée kaiser 02.02.2013 - 15:51

Lire d'autres questions sur les étiquettes