質問: menu managementの管理画面にカスタムメタボックスを追加する方法 wordpressのコアチームがネイティブメニュー管理機能をついに統合したことに非常に感謝していますが、変更したいいくつかの重要な要素に不満を感じます。階層的なカテゴリがリストに表示されるのと同じように表示されるのと同じ方法で階層的なページを表示する方法が必要です。また、メニューに追加できるリンクを手動で含める方法が必要です。どうすればこれができますか?前もって感謝します _ updated _ それで、これが私がやろうとしている二つのことです。現在、デフォルトのワードプレスの「メニュー管理」管理画面にアクセスすると、左側に「ページ」メタボックスを表示するように選択できます。ここでの問題は、「すべて表示」タブをクリックしたときにページのどれも正しく順序付けられておらず、該当する場合はインデントされていないことです。 現在のデフォルトレイアウト: 目的のレイアウト: (親の関係を示すためにそれらをインデントしたことに注意してください。アイテムもそれらのソート順に基づいてソートする必要があります)。さらに、このリストの中で(あるいはもっと簡単ならそれ自身のメタボックスの中で)要素をクリックしてそれらをメニューの中に含めることができるようにチェックボックスリストの形で提示されるリンクをハードコーディングする方法が必要です。これは、 "カスタムリンク"を使用してこれらの要素を手動で追加するのではなく、一覧から選択することをお勧めするためです。
回答: 私はこれに成功しましたが、それは混乱です。基本的に、walkerは以下のパラメータを持つべきです:$this->db_fields['parent'] = 'post_parent'; $this->db_fields['id'] = 'id'; しかし、それを実行するには、既存のメタボックスコールバックを削除してコピーし、1行変更して追加のフィルタを取得して元に戻す必要があります。その後、これらのパラメータを設定した自分のウォーカーを渡すことができます。add_filter( 'admin_head-nav-menus.php', 'wpse2770_admin_head_nav_menus' ); function wpse2770_admin_head_nav_menus() { // hijack "pages" meta box callback with one that has an extra filter for the walker class $globals['wp_meta_boxes']['nav-menus']['side']['default']['add-page']['callback'] = 'wpse2770_wp_nav_menu_item_post_type_meta_box'; // since walker_nav_menu_checklist is not always available, we create this class in this function (didn't even know that was possible...) class wpse2770_walker_nav_menu_checklist extends walker_nav_menu_checklist { public function __construct() { $this->db_fields['parent'] = 'post_parent'; $this->db_fields['id'] = 'id'; } } } add_filter( 'wp_nav_menu_item_post_type_meta_box_walker', 'wpse2770_wp_nav_menu_item_post_type_meta_box_walker', 10, 3 ); function wpse2770_wp_nav_menu_item_post_type_meta_box_walker( $walker, $post_type, $context ) { if ( 'page' == $post_type && 'view-all' == $context ) { $walker = 'wpse2770_walker_nav_menu_checklist'; } return $walker; } function wpse2770_wp_nav_menu_item_post_type_meta_box( $object, $post_type ) { global $_nav_menu_placeholder, $nav_menu_selected_id; $post_type_name = $post_type['args']->name; // paginate browsing for large numbers of post objects $per_page = 50; $pagenum = isset( $_request[$post_type_name . '-tab'] ) && isset( $_request['paged'] ) ? absint( $_request['paged'] ) : 1; $offset = 0 < $pagenum ? $per_page * ( $pagenum - 1 ) : 0; $args = array( 'offset' => $offset, 'order' => 'asc', 'orderby' => 'title', 'posts_per_page' => $per_page, 'post_type' => $post_type_name, 'suppress_filters' => true, 'update_post_term_cache' => false, 'update_post_meta_cache' => false ); if ( isset( $post_type['args']->_default_query ) ) $args = array_merge($args, (array) $post_type['args']->_default_query ); // @todo transient caching of these results with proper invalidation on updating of a post of this type $get_posts = new wp_query; $posts = $get_posts->query( $args ); if ( ! $get_posts->post_count ) { echo '<p>' . __( 'no items.' ) . '</p>'; return; } $post_type_object = get_post_type_object($post_type_name); $num_pages = $get_posts->max_num_pages; $page_links = paginate_links( array( 'base' => add_query_arg( array( $post_type_name . '-tab' => 'all', 'paged' => '%#%', 'item-type' => 'post_type', 'item-object' => $post_type_name, ) ), 'format' => '', 'prev_text' => __('&laquo;'), 'next_text' => __('&raquo;'), 'total' => $num_pages, 'current' => $pagenum )); if ( !$posts ) $error = '<li id="error">'. $post_type['args']->labels->not_found .'</li>'; $walker = 'walker_nav_menu_checklist'; $current_tab = 'most-recent'; if ( isset( $_request[$post_type_name . '-tab'] ) && in_array( $_request[$post_type_name . '-tab'], array('all', 'search') ) ) { $current_tab = $_request[$post_type_name . '-tab']; } if ( ! empty( $_request['quick-search-posttype-' . $post_type_name] ) ) { $current_tab = 'search'; } $removed_args = array( 'action', 'customlink-tab', 'edit-menu-item', 'menu-item', 'page-tab', '_wpnonce', ); ?> <div id="posttype-<?php echo $post_type_name; ?>" class="posttypediv"> <ul id="posttype-<?php echo $post_type_name; ?>-tabs" class="posttype-tabs add-menu-item-tabs"> <li <?php echo ( 'most-recent' == $current_tab ? ' class="tabs"' : '' ); ?>><a class="nav-tab-link" href="<?php if ( $nav_menu_selected_id ) echo esc_url(add_query_arg($post_type_name . '-tab', 'most-recent', remove_query_arg($removed_args))); ?>#tabs-panel-posttype-<?php echo $post_type_name; ?>-most-recent"><?php _e('most recent'); ?></a></li> <li <?php echo ( 'all' == $current_tab ? ' class="tabs"' : '' ); ?>><a class="nav-tab-link" href="<?php if ( $nav_menu_selected_id ) echo esc_url(add_query_arg($post_type_name . '-tab', 'all', remove_query_arg($removed_args))); ?>#<?php echo $post_type_name; ?>-all"><?php _e('view all'); ?></a></li> <li <?php echo ( 'search' == $current_tab ? ' class="tabs"' : '' ); ?>><a class="nav-tab-link" href="<?php if ( $nav_menu_selected_id ) echo esc_url(add_query_arg($post_type_name . '-tab', 'search', remove_query_arg($removed_args))); ?>#tabs-panel-posttype-<?php echo $post_type_name; ?>-search"><?php _e('search'); ?></a></li> </ul> <div id="tabs-panel-posttype-<?php echo $post_type_name; ?>-most-recent" class="tabs-panel <?php echo ( 'most-recent' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' ); ?>"> <ul id="<?php echo $post_type_name; ?>checklist-most-recent" class="categorychecklist form-no-clear"> <?php $recent_args = array_merge( $args, array( 'orderby' => 'post_date', 'order' => 'desc', 'posts_per_page' => 15 ) ); $most_recent = $get_posts->query( $recent_args ); $args['walker'] = new $walker; echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $most_recent), 0, (object) $args ); ?> </ul> </div><!-- /.tabs-panel --> <div class="tabs-panel <?php echo ( 'search' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' ); ?>" id="tabs-panel-posttype-<?php echo $post_type_name; ?>-search"> <?php if ( isset( $_request['quick-search-posttype-' . $post_type_name] ) ) { $searched = esc_attr( $_request['quick-search-posttype-' . $post_type_name] ); $search_results = get_posts( array( 's' => $searched, 'post_type' => $post_type_name, 'fields' => 'all', 'order' => 'desc', ) ); } else { $searched = ''; $search_results = array(); } ?> <p class="quick-search-wrap"> <input type="text" class="quick-search input-with-default-title" title="<?php esc_attr_e('search'); ?>" value="<?php echo $searched; ?>" name="quick-search-posttype-<?php echo $post_type_name; ?>" /> <img class="waiting" src="<?php echo esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" alt="" /> <?php submit_button( __( 'search' ), 'quick-search-submit button-secondary hide-if-js', 'submit', false ); ?> </p> <ul id="<?php echo $post_type_name; ?>-search-checklist" class="list:<?php echo $post_type_name?> categorychecklist form-no-clear"> <?php if ( ! empty( $search_results ) && ! is_wp_error( $search_results ) ) : ?> <?php $args['walker'] = new $walker; echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $search_results), 0, (object) $args ); ?> <?php elseif ( is_wp_error( $search_results ) ) : ?> <li><?php echo $search_results->get_error_message(); ?></li> <?php elseif ( ! empty( $searched ) ) : ?> <li><?php _e('no results found.'); ?></li> <?php endif; ?> </ul> </div><!-- /.tabs-panel --> <div id="<?php echo $post_type_name; ?>-all" class="tabs-panel tabs-panel-view-all <?php echo ( 'all' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' ); ?>"> <?php if ( ! empty( $page_links ) ) : ?> <div class="add-menu-item-pagelinks"> <?php echo $page_links; ?> </div> <?php endif; ?> <ul id="<?php echo $post_type_name; ?>checklist" class="list:<?php echo $post_type_name?> categorychecklist form-no-clear"> <?php // wpse 2770: and this is the filter we want to add! $walker = apply_filters( 'wp_nav_menu_item_post_type_meta_box_walker', $walker, $post_type_name, 'view-all' ); $args['walker'] = new $walker; // if we're dealing with pages, let's put a checkbox for the front page at the top of the list if ( 'page' == $post_type_name ) { $front_page = 'page' == get_option('show_on_front') ? (int) get_option( 'page_on_front' ) : 0; if ( ! empty( $front_page ) ) { $front_page_obj = get_post( $front_page ); $front_page_obj->_add_to_top = true; $front_page_obj->label = sprintf( _x('home: %s', 'nav menu front page title'), $front_page_obj->post_title ); array_unshift( $posts, $front_page_obj ); } else { $_nav_menu_placeholder = ( 0 > $_nav_menu_placeholder ) ? intval($_nav_menu_placeholder) - 1 : -1; array_unshift( $posts, (object) array( '_add_to_top' => true, 'id' => 0, 'object_id' => $_nav_menu_placeholder, 'post_content' => '', 'post_excerpt' => '', 'post_title' => _x('home', 'nav menu home label'), 'post_type' => 'nav_menu_item', 'type' => 'custom', 'url' => home_url('/'), ) ); } } $args['walker']->db_fields['parent'] = 'post_parent'; $checkbox_items = walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $posts), 0, (object) $args ); if ( 'all' == $current_tab && ! empty( $_request['selectall'] ) ) { $checkbox_items = preg_replace('/(type=(.)checkbox(\2))/', '$1 checked=$2checked$2', $checkbox_items); } echo $checkbox_items; ?> </ul> <?php if ( ! empty( $page_links ) ) : ?> <div class="add-menu-item-pagelinks"> <?php echo $page_links; ?> </div> <?php endif; ?> </div><!-- /.tabs-panel --> <p class="button-controls"> <span class="list-controls"> <a href="<?php echo esc_url(add_query_arg( array( $post_type_name . '-tab' => 'all', 'selectall' => 1, ), remove_query_arg($removed_args) )); ?>#posttype-<?php echo $post_type_name; ?>" class="select-all"><?php _e('select all'); ?></a> </span> <span class="add-to-menu"> <img class="waiting" src="<?php echo esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" alt="" /> <input type="submit"<?php disabled( $nav_menu_selected_id, 0 ); ?> class="button-secondary submit-add-to-menu" value="<?php esc_attr_e('add to menu'); ?>" name="add-post-type-menu-item" id="submit-posttype-<?php echo $post_type_name; ?>" /> </span> </p> </div><!-- /.posttypediv --> <?php }