web-dev-qa-db-fra.com

Comment accéder aux menus produits par Dashboard> Apparence> Menus

Une suite à cette question:

Remplacement des fonctionnalités du menu WordPress par un plugin

Depuis que je travaille très rarement avec WordPress (j'ai beaucoup travaillé avec les scripts phpBB, myBB, Concrete5 et custom PHP - mais mon expérience avec WordPress est limitée à un ou deux sites simples), je pense que Je pourrais obtenir une réponse plus rapidement ici que de passer 3 heures à lire la documentation.

Je crée un plugin pour remplacer le menu WordPress par le mien. Jusqu'ici, voici le code pour ce plugin (tout cela dans un seul fichier PHP):

add_action('init', 'DEMenu::init');
class DEMenu {

    public static function init() {
        $DEMenu = new DEMenu();
        load_plugin_textdomain ('de-menu', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/');
        /* Load CSS with wp_enqueue_style() */

        // If in admin page, then load admin page stuff
        if (is_admin()) {
            add_action('admin_menu', 'DEMenu::admin');
        }   
        // If not on admin page ...
        else {
            // Load plugin core - doesn't require a hook
            $DEMenu->core();
        }

    }

    public static function admin() {
        add_options_page('DE Menu Options', 'DE Menu', 'manage_options', 'de-menu', 'DEMenu::options');
//      add_option('de_menu_maintenance', 'off');
    }

    public static function options() {
        if (!current_user_can('manage_options'))  {
            wp_die( __('You do not have sufficient permissions to access this page.') );
        }
        echo '<div class="wrap">';
        echo '<p>Here is where the form would go if I actually had options.</p>';
        echo '</div>';
    }

    public static function core() {

        /* Add support for various themes */
        add_filter('wp_nav_menu', 'DEMenu::display');

        /* If I need to add more actions/filters they will go here... I may enqueue CSS here, too */

    }

    public static function display() {
        print "Let's see if this displays. I'll add some text to ctrl+F for later";
    }

}

C’est principalement l’aboutissement de divers conseils issus de la documentation WordPress, des didacticiels de développement de plug-ins et des pratiques de base de OOP.

Maintenant, je dois dessiner le menu à partir de la zone Tableau de bord> Apparence> Menus. Comment puis-je accéder à cet objet de menu (sous forme de tableau ou autre type de données accessible) afin de pouvoir l'utiliser?

Et je me rends bien compte qu’il semble ridicule de remplacer complètement la sortie de wp_nav_menu() si je veux utiliser le même menu, mais je ne peux penser à aucun autre moyen d’accomplir ce que je veux.

MODIFIER -

J'ai lu wp-includes/nav-menu-template.php pour savoir comment wp_nav_menu() obtient la liste des éléments de menu, ainsi que son affichage. J'essayais essentiellement d'émuler la méthode utilisée par cette fonction uniquement avec de légères variations à ajouter dans la structure multi-colonnes. Voici ce que j'ai jusqu'à présent:

public static function core() {

    /* Add support for varoius themes */
    add_filter('wp_nav_menu', 'DEMenu::display', 1);

    /* If I need to add more actions/filters they will go here... I may enqueue CSS here, too */

}

    public static function display( $args ) {
        /* The following is blatantly ripped from nav-menu-template.php */

            // *****************************************************************
            /* Excluded for ease of reading - this is an exact copy of nav-menu-template.php */
            // *****************************************************************

        // Here we can invoke our custom walker without editing the theme
        $args->walker = 'DEMenu_Walker';

            $items .= walk_nav_menu_tree( $sorted_menu_items, $args->depth, $args );
            unset($sorted_menu_items);

            // *****************************************************************
            /* Excluded for ease of reading - this is an exact copy of nav-menu-template.php */
            // *****************************************************************

//          $nav_menu = apply_filters( 'wp_nav_menu', $nav_menu, $args );
//  
//          if ( $args->echo )
//                  echo $nav_menu;
//          else
//                  return $nav_menu;

        // Rather than checking if we should echo the output, just return it.
        // This is a filter, so the output will be echo'd by the calling function
        return $nav_menu;
    }

Puis plus tard (en dehors de la classe DEMenu):

class DEMenu_Walker Extends Walker_Nav_Menu {

    function __construct() {
        die("We made it to the constructor!");
    }

}

Cependant, j'obtiens l'erreur suivante:

Warning: Attempt to assign property of non-object in /home/coupon/public_html/wp-content/plugins/DE-menu/index.php on line 146

Ce numéro de ligne fait référence à:

$args->walker = 'DEMenu_Walker';

J'ai peut-être envisagé une solution beaucoup plus raisonnable, mais d'après ce que je peux en dire, j'ai besoin d'une classe de marcheur personnalisée (avec des variables privées permettant de suivre le nombre d'éléments affichés et le nombre d'éléments à afficher par colonne) et c’est le seul moyen d’utiliser une classe de marcheur personnalisée sans modifier le thème. Cependant, si je veux utiliser la solution sur laquelle je travaille actuellement, je dois comprendre pourquoi les variables $args sont non-objets alors que wp_nav_menu() a clairement la ligne de code suivante au tout début de la fonction:

$args = (object) $args;

UN AUTRE ÉDIT -

J'ai résolu le problème non-objet. Lorsque wp_nav_menu() appelle le filtre, il l’appelle ainsi:

$nav_menu = apply_filters( 'wp_nav_menu', $nav_menu, $args );

Je n'avais pas compris que cela signifiait que nous faisions passer deux arguments. J'ai modifié la fonction d'affichage comme suit:

public static function display( $nav_menu, $args ){

Et bien sûr modifié l'appel add_filter() comme suit:

add_filter( 'wp_nav_menu', 'DEMenu::display', 1, 2 );

Bien que maintenant je reçois toutes sortes de nouvelles erreurs amusantes.

Fatal error: Using $this when not in object context in /home/coupon/public_html/wp-includes/class-wp-walker.php on line 185

Remarquez que je n’ai absolument apporté aucune modification à WordPress, je ne comprends donc pas pourquoi une erreur est apparue dans le class-wp-walker.php... Je ne comprends pas non plus pourquoi cette erreur s’affiche tout à l’heure. Des idées?

FINAL EDIT -

Avec l'aide de https://stackoverflow.com/questions/6862887/replacing-wordpress-core-functionality-with-a-plugin , j'ai finalement réalisé je peux utiliser le filtre wp_nav_menu_args pour transmettre ma propre classe de promeneur sans copier l'intégralité de la fonction wp_nav_menu(). Je vais utiliser cette solution (résoudre ce problème), bien que comme mentionné ci-dessus - je rencontre un nouveau problème où ma classe de marcheur provoque sa classe mère à une erreur fatale. Je vais poser une nouvelle question à ce sujet, car il s’agit d’un problème qui concerne la classe Walker et non pas l’accès aux éléments de menu ou la transmission d’un programme personnalisé.


Tâche: J'ai besoin que chaque sous-menu (deuxième niveau ou moins) soit divisé en 5 colonnes (soit 5 éléments <ul> distincts, soit des éléments <div> entourés de certains éléments <li>).

1
stevendesu

Premièrement: Utilisez, pour options(), le tutoriel Paramètres API ( ).

Seconde: Examinez la fonction principale et les filtres disponibles. Ensuite, jetez un coup d'œil aux filtres disponibles:

$sorted_menu_items = apply_filters( 'wp_nav_menu_objects', $sorted_menu_items, $args );
$items = apply_filters( 'wp_nav_menu_items', $items, $args );
$items = apply_filters( "wp_nav_menu_{$menu->slug}_items", $items, $args );
0
kaiser