Die große Herausforderung des WordPress-Admin-Menüs vom Januar 2011 (auch bekannt als "Wie löse ich einige Herausforderungen beim Ändern des WordPress-Admin-Menüsystems?")

14

Diese Frage ist ein bisschen einzigartig.

Es ist zum Teil eine "Herausforderung", die ich an das WordPress-Team ( oder andere Personen ) im Zusammenhang mit Trac-Tickets stelle : # 16048 , # 16050 und # 16204 .

Das Ziel

Das Ziel ist es, die drei (3) Probleme zu umgehen, die in der Abbildung unten dargestellt sind, wenn Sie versuchen, den WordPress Admin-Menüabschnitt zu ändern:

  1. Die "Microsite" -Untermenüseite wird hervorgehoben, wenn ein Anwalt bearbeitet wird (dazu müssen wir in der Lage sein, auf das Untermenüelement "aktuell" zuzugreifen , und einige Haken in der Funktion _wp_menu_output () liefern, was hier benötigt wird) .

  2. Holen Sie sich das Attorney Menü Seite Link zu Link zu /wp-admin/edit.php?post_type=attorneywährend der Bearbeitung eines Attorney (und die gleichen benötigten Haken in der _wp_menu_output () Funktion kann damit umgehen) , und

  3. Holen Sie sich den „Microsite“ Link nicht auslösen „Sie haben keine ausreichenden Berechtigungen auf diese Seite zuzugreifen“ Fehler * (dies ist die übelsten ein zu lösen, und ein Haken an dem Rückgabewert vonuser_can_access_admin_page() gut dieses Problem umgehen konnte.)

Screenshot für The Great WordPress Admin Menu Challenge vom Januar 2011
(Quelle: mikeschinkel.com )

Mehr als nur mein Anwendungsfall

Diese drei (3) Probleme betreffen meinen Anwendungsfall, sind jedoch ein Symbol für die Probleme bei der Konfiguration der Admin-Menüs in WordPress.

Einige im WordPress-Team sagten, es sei einfach und implizierten, dass ich etwas verpasse (was möglicherweise richtig ist), aber ich habe dieses Problem wochenlang untersucht und nicht herausgefunden, wie ich es umgehen soll. Deshalb habe ich das unten gezeigte Plugin erstellt ( auch von Gist herunterladbar ) als einfachstes Anwendungsbeispiel der Probleme. Der Code in admin_menu2()ist ziemlich hackisch, aber genau das ist erforderlich, um die Admin-Menüs in WordPress zu ändern.

Beachten Sie, dass ich weder die neuen remove_menu_page()noch die neuen remove_submenu_page()Funktionen in 3.1 verwendet habe, da das Erstellen des Plugins länger gedauert hätte - ich hatte bereits den Code admin_menu2()aus einem vorhandenen Projekt - und ich glaube nicht, dass sie das Problem lösen würden Problem trotzdem.

Was brauche ich?

Ich brauche eines von zwei (2) Dingen:

  1. Eine Lösung für die Probleme, die ich mit diesem Plugin aufdeckte und in dieser Frage und im Screenshot erläutere (BTW, ich werde Ihre Lösung disqualifizieren, wenn Sie PHP Output Buffering verwenden , um einen Teil davon zu lösen) , oder

  2. Damit das WordPress-Team erkennt, dass diese Haken tatsächlich benötigt werden, und um sie dazu zu bringen, ihre Position auf den Tickets zu überdenken.

Wie nimmst du die Herausforderung an?

  1. Laden Sie eine makellose neue Version von WordPress 3.1 herunter und installieren Sie sie (eine Überarbeitung ist wahrscheinlich ausreichend) .

  2. Downloaden, installieren und aktivieren Sie das „The Great Wordpress Admin - Menü Herausforderung Januar 2011“ Plugin unten (oder das Plugin von Gist herunterladen ) , und dann

  3. Befolgen Sie die Anweisungen auf der Plugin-Seite für dieses Plugin (siehe folgenden Screenshot) , laden Sie jedoch den oben gezeigten Screenshot und versuchen Sie dann, die drei (3) beschriebenen Probleme herauszufinden:

Screenshot der Plugin-Anleitung "The Great WordPress Admin Menu Challenge von Jan 2011"
(Quelle: mikeschinkel.com )

Ein Lichtblick

Glücklicherweise bot Andrew Nacin vom WordPress-Team an, sich das anzuschauen, nachdem ich es codiert hatte. Ich poste also hauptsächlich hier, damit er es überprüfen und kommentieren und andere dazu bringen kann, es zu kommentieren. Ich weiß, dass er beschäftigt ist, aber ich hoffe, dass er (oder Sie) sich die Zeit nehmen können, um dieses Plugin auf einer ursprünglichen Installation von Version 3.1 zu installieren und zu prüfen, ob er das Problem beheben kann.

Wenn Sie zustimmen, ist die Herausforderung unmöglich?

Wenn Sie nach dem Versuch, diese Herausforderung zu bestehen, zu dem gleichen Ergebnis kommen wie ich und möchten , dass die WordPress Admin-Menüs besser konfigurierbar sind, kommentieren Sie diese Trac-Tickets ( Nr. 16048 - Nr. 16050 - Nr. 16204 ) und stimmen Sie dieser Frage zu Unterstützung dafür zu zeigen.

Ich gebe gerne zu, dass ich etwas verpasst habe, wenn ich es getan habe

Natürlich ist es möglich, dass ich völlig hirntot bin und jemand genau darauf hinweist, wie es geht. Eigentlich hoffe ich wirklich, dass dies der Fall sein wird; Ich liege lieber falsch und möchte, dass dies funktioniert, als umgekehrt.

Und hier ist das Plugin

Sie können auch von Gist herunterladen :

<?php
/*
Plugin Name: The Great WordPress Admin Menu Challenge of Jan 2011
Description: <em>"The Great WordPress Admin Menu Challenge of Jan 2011"</em> was inspired by the WordPress team's apparent lack of understanding of the problems addressed by trac tickets <a href="http://core.trac.wordpress.org/ticket/16048">#16048</a> and <a href="http://core.trac.wordpress.org/ticket/16050">#16050</a> <em>(See also: <a href="http://core.trac.wordpress.org/ticket/16204">#16204</a>)</em> and suggestion that the <a href="http://wordpress.org/extend/plugins/admin-menu-editor/>Admin Menu Editor</a> plugin handles the use-cases that the tickets address. Debate spilled over onto Twitter with participation from <a href="http://twitter.com/nacin">@nacin</a>, <a href="http://twitter.com/aaronjorbin">@aaronjorbin</a>, <a href="http://twitter.com/petemall">@petemall</a>, <a href="http://twitter.com/westi">@westi</a>, <a href="http://twitter.com/janeforshort">@janeforshort</a>, <a href="http://twitter.com/PatchesWelcome">@PatchesWelcome</a>; supportive comments from <a href="http://twitter.com/ramsey">@ramsey</a>, <a href="http://twitter.com/brianlayman">@brianlayman</a>, <a href="http://twitter.com/TheLeggett">@TheLeggett</a>, a retweeting of @nacin's simple yet <em>(AFAICT)</em> insufficient solution by <a href="http://twitter.com/vbakaitis">@vbakaitis</a>, <a href="http://twitter.com/Viper007Bond">@Viper007Bond</a>, <a href="http://twitter.com/nickopris">@nickopris</a>, <a href="http://twitter.com/Trademark">@Trademark</a>, <a href="http://twitter.com/favstar_pop">@favstar_pop</a>, <a href="http://twitter.com/designsimply">@designsimply</a>, <a href="http://twitter.com/darylkoop">@darylkoop</a>, <a href="http://twitter.com/iamjohnford">@iamjohnford</a>, <a href="http://twitter.com/markjaquith">@markjaquith</a>, <a href="http://twitter.com/JohnJamesJacoby">@JohnJamesJacoby</a> and <a href="http://twitter.com/dd32">@dd32</a>. Also see <a href="http://andrewnacin.com/2010/12/20/better-admin-menu-controls-custom-post-types-wordpress-3-1/#comment-6360">comments</a> on @nacin's blog post entitled "<em>Better admin menu handling for post types in WordPress 3.1</em>." <strong>The desired goal of the <em>"challenge"</em></strong> is to simply either to find a solution that has eluded me or, to get those who are dismissing it as solvable without added hooks in WordPress to have a tangible example to explore in hopes they will recognize that there is indeed a need for at least some of the requested hooks. <strong>There are three (3) steps to the challenge:</strong> 1.) Get the "Microsite" submenu page to be highlighted when editing an Attorney, 2.) Get the Attorney Menu Page link to link <a href="/wordpress//wp-admin/edit.php?post_type=attorney">here</a>  when editing an Attorney, and 3.) Get the "Microsite" link not to trigger a "You do not have sufficient permissions to access this page" error.  Here is <a href="https://mikeschinkel.com/websnaps/skitched-20110114-235302.png" target="_blank"><strong>a screenshot</strong> that attempts to illustrate the callenge</a>. The code can be found on gist <a href="https://gist.github.com/780709"><strong>here</strong></a>. Activate it as a plugin in a WordPress 3.1 install and go <a href="/wordpress//wp-admin/post.php?post=10&action=edit"><strong>here</strong></a> to see what the screenshot illustrates. <strong>Be sure to load the <a href="https://mikeschinkel.com/websnaps/skitched-20110114-235302.png" target="_blank">screenshot</a> in another browser tab or window first</strong>.
Author:      Mike Schinkel
Author URI:  http://about.me/mikeschinkel
Plugin URI:  https://gist.github.com/780709
*/
if (!class_exists('TheGreatWordPressAdminMenuChallenge')) {
  class TheGreatWordPressAdminMenuChallenge {
    static function on_load() {
      add_action('init',array(__CLASS__,'init'));
      add_action('admin_menu',array(__CLASS__,'admin_menu1'));      // Simulates generic "Microsite" plugin
      add_action('admin_menu',array(__CLASS__,'admin_menu2'),100);  // Simulates website-specific plugin
      add_action('post_row_actions',array(__CLASS__,'post_row_actions'),10,2);
    }
    static function post_row_actions($actions,$post) {
      $url = admin_url(self::this_microsite_url($post->ID));
      $actions = array_merge(array('microsite'=>"<a href=\"{$url}\" title=\"Manage this Microsite\">Microsite</a>"),$actions);
      return $actions;
    }
    static function the_microsite_editor() {
      echo "We are in the Microsite Editor for " . self::post_title();
    }
    static function admin_menu1() {
      if (self::this_post_id() && in_array(self::this_post_type(),array('attorney','practice_area'))) {
        add_submenu_page(
          self::this_parent_slug(),
          self::microsite_page_title(),
          self::microsite_page_title(),
          $capability = 'edit_posts',
          'microsite',
          array($microsite,'the_microsite_editor')
        );
        global $wp_post_types;
        $parent_type_meta = $wp_post_types[self::this_post_type()];
        global $menu;
        $slug = false;
        foreach($menu as $index => $menu_page)
          if ($menu_page[0]===$parent_type_meta->label) {
            $slug = $menu_page[2];
            break;
          }
        if ($slug) {
          global $pagenow;
          global $submenu;
          // Setting this makes gives the link to the microsite in the menu the highlight for "current" menu option
          global $submenu_file;
          $submenu_file = self::this_microsite_url();
          $index = end(array_keys($submenu[$slug]));
          $submenu[$slug][$index][12] = $submenu_file;
        }
      }
    }
    static function this_parent_slug() {
      return "edit.php?post_type=" . self::this_post_type();
    }
    static function post_title() {
      $post_id = self::this_post_id();
      return ($post_id ? get_post($post_id)->post_title : false);
    }
    static function microsite_page_title() {
      return 'Microsite for ' . self::post_title();
    }
    static function this_post_type($get_post=true) {
      $post_type = (isset($_GET['post_type']) ? $_GET['post_type'] : false);
      if (!$post_type && $get_post) {
        $post_id = self::this_post_id();
        $post_type = get_post($post_id)->post_type;
      }
      return $post_type;
    }
    static function this_post_id() {
      $post_id = false;
      $post_type = self::this_post_type(false);
      if (isset($_GET[$post_type]))
        $post_id = intval($_GET[$post_type]);
      else if (isset($_GET['post']))
        $post_id = intval($_GET['post']);
      return $post_id;
    }
    static function this_microsite_url($post_id=false) {
      $post_type = self::this_post_type();
      $post_id = $post_id ? intval($post_id) : self::this_post_id();
      return "edit.php?post_type={$post_type}&page=microsite&attorney={$post_id}";
    }
    static function admin_menu2() {
      // The code required for this is super, nasty, ugly and shouldn't be, but at least it *is* doable
      global $menu;
      global $submenu;
      global $microsite;

      $parent_type = self::this_post_type();
      foreach(array('attorney','practice_area') as $post_type) {
        $slug = "edit.php?post_type={$post_type}";
        if ($post_type==$parent_type) {  // If a microsite remove everything except the microsite editor
          $microsite_url = self::this_microsite_url();
          foreach($submenu[$slug] as $submenu_index => $submenu_page) {
            if ($submenu_page[2]!=$microsite_url) {
              unset($submenu[$slug][$submenu_index]);
            }
          }
        } else {
          $submenu[$slug] = array();
        }
      }

       // Remove the Submenus for each menu
      unset($submenu['index.php']);
      unset($submenu['edit.php?post_type=article']);
      unset($submenu['edit.php?post_type=event']);
      unset($submenu['edit.php?post_type=case_study']);
      unset($submenu['edit.php?post_type=news_item']);
      unset($submenu['edit.php?post_type=transaction']);
      unset($submenu['edit.php?post_type=page']);
      unset($submenu['upload.php']);

      unset($submenu['users.php'][13]); // Removed the "Add New"

      $remove = array_flip(array(
        'edit.php',
        'link-manager.php',
        'edit-comments.php',
        'edit.php?post_type=microsite-page',
      ));
      if (!current_user_can('manage_tools'))
        $remove['tools.php'] = count($remove);

      foreach($menu as $index => $menu_page) {
        if (isset($remove[$menu_page[2]])) {
          unset($submenu[$menu_page[2]]);
          unset($menu[$index]);
        }
      }

      $move = array(
        'edit.php?post_type=page' => array( 'move-to' => 35,  0 => 'Other Pages' ),
        'separator2' => array( 'move-to' => 40 ),
        'upload.php' => array( 'move-to' => 50, 0 => 'Media Library' ),
      );
      $add = array();
      foreach($menu as $index => $menu_page) {
        if (isset($move[$menu_page[2]])) {
          foreach($move[$menu_page[2]] as $value_index => $value) {
            if ($value_index==='move-to') {
              $move_to = $value;
            } else {
              $menu_page[$value_index] = $value;
            }
          }
          $add[$move_to] = $menu_page;
          unset($menu[$index]);
        }
      }
      foreach($add as $index => $value)
        $menu[$index] = $value;

      add_menu_page(
        'Attorney Positions',
        'Attorney Positions',
        'edit_posts',
        'edit-tags.php?taxonomy=attorney-position&amp;post_type=attorney',
        false,
        false,
        55);

      ksort($menu); // Need to sort or it doesn't come out right.
    }
    static function init() {
      register_post_type('attorney',array(
        'label'           => 'Attorneys',
        'public'          => true,
      ));
      register_post_type('practice_area',array(
        'label'           => 'Practice Areas',
        'public'          => true,
      ));
      register_taxonomy('attorney-position','attorney',array(
        'label'=>'Attorney Positions',
      ));
      register_post_type('article',array(
        'label'           => 'Articles & Presentations',
        'public'          => true,
      ));
      register_post_type('case_study',array(
        'label'           => 'Case Studies',
        'public'          => true,
      ));
      register_post_type('news_item',array(
        'label'           => 'Firm News',
        'public'          => true,
      ));
      register_post_type('event',array(
        'label'           => 'Events',
        'public'          => true,
      ));
      register_post_type('transaction',array(
        'label'           => 'Transactions',
        'public'          => true,
      ));

      // Install the test data
      $post_id = 10;
      $attorney = get_post($post_id);
      if (!$attorney) {
        global $wpdb;
        $wpdb->insert($wpdb->posts,array(
          'ID' => $post_id,
          'post_title' => 'John Smith',
          'post_type' => 'attorney',
          'post_content' => 'This is a post about the Attorney John Smith.',
          'post_status' => 'publish',
          'post_author' => 1,
        ));
      }
    }
  }
  TheGreatWordPressAdminMenuChallenge::on_load();
}

Ich hoffe sehr, dass Sie allen, die dies lesen, helfen können.

Danke im Voraus.

MikeSchinkel
quelle
Ich bin interessiert (und muss meine Erfahrung mit der Admin-Seite wirklich verbessern), werde aber wahrscheinlich auf die endgültige Version 3.1 warten. Mein lokaler Teststack ist nicht sehr gut für mehrere Core-Versionen geeignet, daher halte ich mich an den aktuellen Stable.
Rarst
Ich kenne genau das Problem, von dem du sprichst, ich glaube nicht, dass ich es besser beschreiben kann als du, aber ich habe die gleichen Probleme gesehen, als ich ein Dropdown-Menü für den Administrator geschrieben habe (zum Spaß), nur um es hinzuzufügen meine +1.
t31os
@ t310s - Vielen Dank, dass Sie Ihre +1 hinzugefügt haben. Es hat mich wahrscheinlich 2 Wochen nach der Forschung in der Lage zu sein , das Problem zu beschreiben, so dass der Tat kann man auch erkennen , dass es relevant ist (und nicht in den 2 Wochen habe ich verbrachte) heißt , Sie sind weit voraus fast jeder auf diesem, einschließlich mir!
MikeSchinkel

Antworten:

2

Mike, ich habe mir den Code und Ihren idealen Endanwendungsfall angesehen ... und einige davon sind, ehrlich gesagt, mit dem aktuellen System nicht möglich. Wieder Ihre Anforderungen:

  1. Lassen Sie die Untermenüseite "Microsite" hervorheben, wenn Sie einen Anwalt bearbeiten
  2. Rufen Sie den Link zur Anwaltsmenüseite auf, auf den Sie /wp-admin/edit.php?post_type=attorneybeim Bearbeiten eines Anwalts verweisen können
  3. Rufen Sie den Link "Microsite" ab, um nicht den Fehler "Sie haben nicht genügend Berechtigungen, um auf diese Seite zuzugreifen" auszulösen

Und das Schlüsselproblem ist hier # 2.

Was ich versucht habe

Ich habe versucht, einen benutzerdefinierten Beitragstyp für Anwälte hinzuzufügen, und wurde sofort daran erinnert, /wp-admin/edit.php?post_type=attorneydass Sie eine Liste von Anwälten erhalten, nicht einen tatsächlichen Bearbeitungsbildschirm. Die eigentliche Bearbeitung erfolgt am /wp-admin/post.php?post=10&action=edit. Wenn Sie also wirklich an Nummer 2 gebunden sind, funktionieren die beiden anderen Kriterien nicht.

Dies ist der Grund, warum # 3 bei der Implementierung fehlschlägt ... und ich nicht einmal in der Lage war, # 1 zu versuchen, weil ich nicht so weit kommen konnte.

EAMann
quelle
Glauben Sie, dass Ihre Analyse korrekt ist. Bei dem in Frage kommenden Layout handelt es sich um ein Layout, bei dem ich mehr als einen Kundenwunsch hatte, um die Menüstrukturen für ihre Anwendungsfälle zu vereinfachen. Ich habe vorgeschlagen, Untermenüs zu verwenden, aber das hat ihnen nicht gefallen. Sie hielten es für zu verwirrend für ihre Benutzer. Eine Sache, die ich vielleicht nicht erwähnt habe, ist, dass ich ein Produkt entwickle, das auf WordPress basiert, damit sie es vertreiben können, im Gegensatz zu einer WordPress-Website, auf der ich sie nur darin schulen kann, wie man Dinge zum Laufen bringt. Die andere Möglichkeit ist, WordPress zu verlassen. nicht das, was ich will, dass sie tun.
MikeSchinkel
2

Hey Mike, dein Problem Nr. 3 ist darauf zurückzuführen, dass du angibst ($microsite, 'the_microsite_editor'), wo es sein soll (__CLASS__, 'the_microsite_editor').

Update: Nachdem ich viel zu viel Zeit damit verbracht habe, ähnliche Probleme für mein eigenes Plugin zu lösen, habe ich Folgendes herausgefunden, das bei Ihrer Herausforderung hilfreich sein kann (beachten Sie, dass die Funktionen Methoden unter Ihrer Klasse sind):

function add_posttype_submenu_page($mytype, $label, $cap, $slug) {  
    /* we add two submenu pages to work around the 
       edit.php?post_type=...&page=...problem and have 
       our page called as admin.php?page=... instead */
    //first create a 'blind' pseudo-entry to register our page callback
    add_submenu_page($mytype, $label, $label, $cap, $slug, 
                     array( &$this, 'admin_'.$mytype ));
    //then create a real entry that 'calls' our pseudo-entry
    add_submenu_page('edit.php?post_type='.$mytype, $label, 
                     $label, $cap, 'admin.php?page='.$slug);
    /* then lets fix/hack the highlighting */
    global $plugin_page;
    global $submenu_file;
    if ($plugin_page == $slug) {
        // this next line highlights the submenu entry
        $submenu_file = 'admin.php?page='.$slug; 
        add_filter('parent_file', 
                   array(&$this, 'evil_parent_file_hack'));
    }
} 

function evil_parent_file_hack() {
    //we do this to get the parent menu properly highlighted, too
    //it only gets called on the submenu menu page in question
    global $self;
    global $parent_file;
    $self = $parent_file;
    remove_filter('parent_file', array(&$this, 'evil_parent_file_hack'));
}

Dann rufst du einfach add_posttype_submenu_page()mit den entsprechenden Parametern auf. Damit sollte ein Untermenüelement ordnungsgemäß zu einem Menü hinzugefügt werden, das während eines register_post_type()Anrufs automatisch erstellt wurde .

Wyrfel
quelle
oops ... die doppelten Unterstriche um CLASS wurden fett formatiert ;-)
wyrfel
Ich habe es repariert. :)
fuxia
Oh, das ist einfach großartig. Vielen Dank! Wie hätte ich diesen ersten Punkt verpassen können?!? Doh!
MikeSchinkel
Danke, Mike. Zurück zum ursprünglichen Thema ... WP generiert intern eine ID für einige Menüeinträge und speichert sie in Wert 4 der Menü-Arrays. Wie die Plugin-Page-Hooks. Für benutzerdefinierte Posttypen wird jedoch eine ID gespeichert, die nicht mit dem Plugin-Page-Hook-Format übereinstimmt. Ich denke , dass eine ganze Menge geholfen werden könnte , wenn WP würde diesen konsistent machen (dh Seite Haken für alles erstellen und sie assoziieren Menüeinträge miteinander verwenden, anstatt Untermenü Befestigung mittels der ‚Mutter Slug / file‘.
wyrfel