Ocak 2011'deki Büyük WordPress Yönetici Menüsü Mücadelesi (WordPress Yönetici Menü Sistemini Değiştirirken Bazı Zorluklar Nasıl Çözülür?)


14

Bu soru biraz benzersiz.

Kısmen trac biletlerle ilgili WordPress ekibine ( ya da başka birine ) : " 16048 , # 16050 ve # 16204" yayınladığım bir "meydan okuma" dır .

Amaç

Amaç, WordPress Yönetici menüsü bölümünü değiştirmeye çalışırken aşağıdaki ekran görüntüsünde gösterilen üç (3) sorunu ele almaktır:

  1. Bir Avukat düzenlerken vurgulanacak "Microsite" alt menü sayfasını alın (bunun için bir şekilde alt menü öğesine "current" uygulayabilmemiz gerekir, _ ve _wp_menu_output () işlevindeki bazı kancalar burada gerekenleri sağlar) ,

  2. /wp-admin/edit.php?post_type=attorneyBir Avukat düzenlerken bağlantı kurmak için Avukat Menü Sayfası bağlantısını alın (ve _wp_menu_output () işlevindeki aynı gerekli kancalar bunu halledebilir) ve

  3. " Bu sayfaya erişmek için yeterli izniniz yok" hatasını * tetiklememek için "Microsite" bağlantısını alın * (bu çözüm için en nazik olanıdır ve dönüş değerinin üzerindekiuser_can_access_admin_page() bir kanca bu sorunu iyi işleyebilir.)

The Great WordPress Admin Menu Challenge of Jan 2011 paketi için ekran görüntüsü
(kaynak: mikeschinkel.com )

Benim kullanım durumumdan daha fazlası

Bu üç (3) sorun benim kullanım durumum içindir, ancak WordPress'te yönetici menülerini yapılandırmayla ilgili sorunların simgesidir.

WordPress ekibindeki birkaç kişi kolay olduğunu ve bu nedenle bir şey eksik olduğumu ima etti (ki bu doğru olabilir) ama haftalarca bu soruna baktım ve nasıl çözüleceğini anlayamadım, böylece aşağıda gördüğünüz eklentiyi oluşturdum ( Gist'ten de indirilebilir ) sorunların en basit kullanım örneği olarak. İçindeki kod admin_menu2()oldukça acayip ama WordPress'te Yönetici Menülerini değiştirmek için gereken şey bu.

Eklenti oluşturmak için daha uzun süreceği için 3.1'de yeni remove_menu_page()veya yeni remove_submenu_page()işlevleri kullanmaya çalışmadım - zaten admin_menu2()mevcut bir projeden kod aldım - ve bunların ele alınacağına inanmıyorum sorun yine de.

Neye ihtiyacım var?

İki (2) şeyden birine ihtiyacım var:

  1. Bu eklenti ile ortaya koyduğum ve bu soruda ve ekran görüntüsünde açıkladığım sorunlara bir çözüm (BTW, bunun herhangi bir bölümünü çözmek için PHP Çıktı Tamponlama kullanırsanız çözümünüzü diskalifiye edeceğim ) veya

  2. WordPress Ekibinin bu kancalara gerçekten ihtiyaç duyulduğunu tanıması ve bilet üzerindeki konumlarını yeniden gözden geçirmelerini sağlamak.

Görevi Nasıl Ele Alırsınız?

  1. WordPress 3.1'in bozulmamış yeni bir kopyasını indirip yükleyin (herhangi bir düzeltme muhtemelen yapar) ,

  2. Aşağıdaki "Ocak 2011'in Harika WordPress Yönetici Menüsü Mücadelesi" eklentisini indirin, yükleyin ve etkinleştirin (veya eklentiyi Gist'ten indirin ) ve ardından

  3. Bu eklenti için eklenti sayfasında bulunan talimatları izleyin (aşağıdaki ekran görüntüsüne bakın), ancak temel olarak yukarıda gördüğünüz ekran görüntüsünü yükleyin ve sonra açıklanan üç (3) sorunu anlamaya çalışın:

Eklenti talimatları "Ocak 2011 Büyük WordPress Yönetici Menüsü Challenge" ekran görüntüsü
(kaynak: mikeschinkel.com )

Bir Umut Işığı

Neyse ki WordPress ekibinden Andrew Nacin, kodladığımda buna bakmayı teklif etti, bu yüzden öncelikle onu gözden geçirmesi ve yorumlaması ve başkalarının yorum yapması için buraya gönderiyorum. Meşgul olduğunu biliyorum ama umarım o (hatta siz) bu eklentiyi v3.1'in bozulmamış bir kurulumuna yüklemek için zaman alabilir ve sorunu çözüp çözemeyeceğini görebilirsiniz.

Kabul Ediyorsanız Meydan Okuma İmkansız mı?

Bu meydan okumayı denedikten sonra benimle aynı sonuca ulaşırsanız ve WordPress Yönetici menülerinin daha yapılandırılabilir olmasını istiyorsanız, lütfen bu trac biletlerine ( # 16048 - # 16050 - # 16204 ) yorum yapın ve bu soruyu oylayın ona destek vermek.

Bir şeyi kaçırdığımı memnuniyetle kabul ederim, eğer yaparsam

Tabii ki bu konuda tamamen beyin ölü olabilirim ve birisi tam olarak nasıl yapılacağına işaret edebilir. Aslında, umarım bu durum böyle olur; Yanlış olmayı tercih ederim ve bunun tam tersi.

Ve İşte Eklenti

Gist'ten aşağıdaki durumlarda da indirilebilir :

<?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();
}

Bunu okuyan herkese gerçekten yardımcı olabileceğinizi umuyorum.

Şimdiden teşekkürler.


İlgileniyorum (ve gerçekten yönetici tarafı ile deneyimimi yükseltmeliyim), ancak muhtemelen 3.1 son sürümü bekleyecek. Yerel test yığınım birden fazla çekirdek sürümü için çok uygun değil, bu yüzden mevcut kararlılığa bağlı kalıyorum.
Rarst

Mike hakkında konuştuğunuz problemi tam olarak biliyorum, orada olduğundan daha iyi tarif edebileceğimi sanmıyorum, ancak yönetici için bir açılır menü yazarken aynı sorunları gördüm (eğlence için), sadece ekleyerek + 1'im.
t31os

@ t310s - + 1'inizi eklediğiniz için teşekkür ederiz. Sorunu tanımlayabilmem muhtemelen 2 hafta sürdü, bu yüzden konunun alakalı olduğunu (ve sahip olduğum 2 haftayı geçirmediklerini bile) fark edebilmeniz bile , bu konudaki herkesin çok önünde olduğunuz anlamına geliyor. ben mi!
MikeSchinkel

Yanıtlar:


2

Mike, koda bir göz attım ve ideal son kullanım durumun ... ve bazıları, mevcut sistemle açıkçası mümkün değil. Yine, gereksinimleriniz:

  1. Bir Avukat düzenlerken vurgulanacak "Mikrosite" alt menü sayfasını edinin
  2. /wp-admin/edit.php?post_type=attorneyBir Avukat düzenlerken bağlanmak için Avukat Menü Sayfası bağlantısını alın
  3. "Bu sayfaya erişmek için yeterli izniniz yok" hatasını tetiklememek için "Microsite" bağlantısını alın

Ve buradaki kilit mesele # 2.

Ne denedim

Avukatlar için özel bir yazı türü eklemeyi denedim ve /wp-admin/edit.php?post_type=attorneysize gerçek bir düzenleme ekranı değil, bir avukat listesi verecek olan hemen hatırlatıldı . Gerçek düzenleme tarihinde gerçekleşir /wp-admin/post.php?post=10&action=edit. Eğer gerçekten # 2'ye bağlıysanız ... diğer iki kriter işe yaramaz.

Bu yüzden # 3 uygulamada başarısız oluyor ... ve # 1 girişiminde bile bulunamadım çünkü o kadar uzağa gidemedim.


Analizinizin doğru olduğuna inanıyoruz. Söz konusu düzen, kullanım durumları için menü yapılarını basitleştirmek için hedeflerinde birden fazla müşteri isteğine sahip olduğum düzen. Alt menüler kullanmayı teklif ettim ama bundan hoşlanmadılar; kullanıcıları için çok kafa karıştırıcı olacağını düşündüler. Bahsetmediğim bir şey, bir şeyleri nasıl çalıştıracaklarını öğrenmek için onları eğitebileceğim bir WordPress web sitesine karşı dağıtmaları için WordPress'e dayalı bir ürün geliştiriyorum. Diğer seçenekleri WordPress'i terk etmektir; yapmalarını istediğim gibi değil.
MikeSchinkel

2

Merhaba Mike, 3 numaralı sorununuz ($microsite, 'the_microsite_editor'), nerede olması gerektiğini belirtmenizden kaynaklanıyor (__CLASS__, 'the_microsite_editor').

Güncelleme: Kendi eklentim için benzer bir sorunu çözmek için çok fazla zaman harcadıktan sonra, Challenge'ınıza yardımcı olabilecek bir şey buldum (işlevlerin sınıfınızın altındaki yöntemler olduğunu unutmayın):

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

Sonra sadece add_posttype_submenu_page()uygun parametrelerle arayın . Bu, register_post_type()arama sırasında otomatik olarak oluşturulan menüye bir alt menü öğesi eklemelidir .


ayy ... SINIF çevresindeki çift alt çizgiler kalın biçimlendirmeye dönüştürüldü ;-)
wyrfel

Düzelttim. :)
fuxia

Oh, bu sadece harika; Teşekkürler! İlk noktayı nasıl kaçırmış olabilirim?!? Doh!
MikeSchinkel

Teşekkürler, Mike. Orijinal konunuza dönün ... WP dahili olarak bazı menü girişleri için bir kimlik oluşturur ve bunu menü dizilerinin 4. değerinde saklar. Eklenti sayfası kancaları gibi. Ancak, özel posta türleri için eklenti sayfası kanca biçimiyle tutarsız bir kimlik saklar. WP bu tutarlı yapacak bir sürü yardımcı olabilir düşünüyorum (yani her şey için sayfa kanca oluşturmak ve 'üst slug / dosya' aracılığıyla alt menüler eklemek yerine, menü girişlerini birbirleriyle ilişkilendirmek için kullanın.
wyrfel
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.