Как добавить пользовательский метабокс на экран администратора управления меню?

wordpress.stackexchange https://wordpress.stackexchange.com/questions/2770

Вопрос

Хотя я очень благодарен основной команде WordPress, что они наконец интегрировали возможности управления меню, я расстроен некоторыми ключевыми элементами, которые я хотел бы изменить.

Мне нужен способ показать страницы, которые являются иерархическими, так же, как иерархические категории, вместо того, чтобы быть в списке, и мне нужен способ вручную, включая ссылки, которые можно добавить в меню.

Как это может быть сделано?

заранее спасибо

ОбновленоИтак, вот две вещи, которые я пытаюсь сделать. В настоящее время, если вы перейдете на экран администратора «Управление меню» по умолчанию, вы можете выбрать для отображения метабокс «страницы» слева. Проблема здесь заключается в том, что когда вы нажимаете на вкладку «Просмотреть все», ни одна из страниц не заказывается правильно, и они не являются отступами, если это применимо.

Текущий макет по умолчанию:

CURRENT DEFAULT WP ORGANIZATION

Желаемая макет: (Обратите внимание, что я только что отступил, чтобы показать родительские отношения, элементы также должны быть отсортированы на основе их сортировки).

what i would like

Кроме того, в этом списке (или, если проще, в пределах своего собственного метабокс) мне нужен какой -то способ жестких кодирующих ссылок, которые должны быть представлены в форме списка флажков, чтобы можно было щелкнуть элементы и включить их в меню. Причина этого заключается в том, что вместо того, чтобы вручную добавлять эти элементы, используя «пользовательские ссылки», я бы предпочел выбрать их из списка.

Это было полезно?

Решение

Я преуспел в этом, но это беспорядок. По сути, у пешеходов должны быть следующие параметры:

$this->db_fields['parent'] = 'post_parent';
$this->db_fields['id'] = 'ID';

Но, чтобы получить это на месте, вам нужно вырвать существующий обратный вызов метабокс, скопировать его, изменить одну строку, чтобы получить дополнительный фильтр и поместить его обратно. Тогда вы можете передать свой собственный ходун, у которого есть эти параметры.

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
}

Другие советы

Это то, что должно быть помещено в билет на WordPress Trac для группы пользовательского интерфейса. http://core.trac.wordpress.org/

(Редактировать: Связанный билет есть #14660-Список иерархических страниц в WP-Admin/Nav-Menus.php)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с wordpress.stackexchange
scroll top