Snippets

Willy Bahuaud Liste automatiquement des sous-menus

You are viewing an old version of this snippet. View the current version.
Revised by Willy Bahuaud 29c10af
<?php

/**
Plugin name: Submenu auto
Description: Automatically list submenu entries
Author: willybahuaud
*/

add_filter( 'wp_edit_nav_menu_walker', 'willy_wp_edit_nav_menu_walker' );
function willy_wp_edit_nav_menu_walker( $walker ) {
    $walker = 'Willy_Walker_Nav_Menu_Edit';
    return $walker;
}

add_action( 'admin_init', 'willy_menu_pirouette' );
function willy_menu_pirouette() {
    require_once ABSPATH . 'wp-admin/includes/nav-menu.php';
    class Willy_Walker_Nav_Menu_Edit extends Walker_Nav_Menu_Edit {
        public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
            // Get item start_el from parent class
            $temp = '';
            Walker_Nav_Menu_Edit::start_el( $temp, $item, $depth, $args, $id );

            // Add my new fields
            $input = sprintf( '<input type="number" style="width:3em;" name="menu-item-autolist-number[%1$s]" step="1" min="-1" value="%2$s">',
                $item->ID,
                is_int( $item->autolist_number ) && true === $item->autolist ? $item->autolist_number : get_option( 'posts_per_page' )
            );
            $re = '/(<p class="field-description[\S\s]*?<\/p>)/';
            $subst = '$1' . vsprintf( '<p class="field-autolist description"><label for="edit-menu-item-autolist-%1$s">
                <input type="checkbox" id="edit-menu-item-autolist-%1$s" value="oui" name="menu-item-autolist[%1$s]"%2$s /> %3$s
            </label>
				</p>', array(
                    $item->ID,
                    checked( true, $item->autolist, false ),
                    sprintf( __( 'Lister automatiquement %1$s %2$s' ),
                        $input,
                        'sous-éléments'
                    ),
                ) );
            $output .= preg_replace( $re, $subst, $temp );
        }
    }
}

add_filter( 'manage_nav-menus_columns', 'willy_manage_nav_menus_columns', 11 );
function willy_manage_nav_menus_columns( $columns ) {
    $columns['autolist'] = 'Afficher les listes de sous-menus automatiques';
    return $columns;
}

// apply_filters( 'default_hidden_columns', $hidden, $screen );

add_action( 'wp_update_nav_menu_item', 'willy_wp_update_nav_menu_item', 11, 3 );
function willy_wp_update_nav_menu_item( $menu_id, $menu_item_db_id, $args ) {
    $value = isset( $_REQUEST['menu-item-autolist'][ $menu_item_db_id ] ) ? true : false;
    update_post_meta( $menu_item_db_id, 'menu-item-autolist', $value );
    $value_num = $value ? intval( $_REQUEST['menu-item-autolist-number'][ $menu_item_db_id ] ) : false;
    update_post_meta( $menu_item_db_id, 'menu-item-autolist-number', $value_num );
}

add_filter( 'wp_setup_nav_menu_item', 'willy_wp_setup_nav_menu_item' );
function willy_wp_setup_nav_menu_item( $menu_item ) {
    $menu_item->autolist = boolval( get_post_meta( $menu_item->ID, 'menu-item-autolist', true ) );
    $menu_item->autolist_number = intval( get_post_meta( $menu_item->ID, 'menu-item-autolist-number', true ) );
    return $menu_item;
}

add_filter( 'wp_get_nav_menu_items', 'willy_autolist_wp_nav_menu_objects' );
function willy_autolist_wp_nav_menu_objects( $items ) {
    if ( ! is_admin() ) {
        foreach ( $items as $item ) {
            if ( $item->autolist && is_int( $item->autolist_number ) && 0 !== $item->autolist_number ) {
                switch ( $item->type ) {
                    case 'post_type_archive':
                        $autolist = get_autolist_for_archive( array(
                            'post_type' => $item->object,
                            'number'    => $item->autolist_number,
                            'parent'    => $item,
                            'count'     => count( $items ),
                        ) );
                        break;
                    case 'post_type':
                        if ( $item->object_id === get_option( 'page_for_posts' ) ) {
                            $autolist = get_autolist_for_archive( array(
                                'post_type' => 'post',
                                'number'    => $item->autolist_number,
                                'parent'    => $item,
                                'count'     => count( $items ),
                            ) );
                        } else {
                            $autolist = get_autolist_for_post_parent( array(
                                'post_type'   => $item->object,
                                'post_parent' => $item->object_id,
                                'number'      => $item->autolist_number,
                                'parent'      => $item,
                                'count'       => count( $items ),
                            ) );
                        }
                        break;
                    case 'taxonomy':
                        $autolist = get_autolist_for_taxonomy( array(
                            'taxonomy' => $item->object,
                            'term_id'  => $item->object_id,
                            'number'   => $item->autolist_number,
                            'parent'   => $item,
                            'count'    => count( $items ),
                        ) );
                        break;
                }
                if ( ! empty( $autolist ) ) {
                    $items = array_merge( $items, $autolist );
                }
            }
        }
    }
    return $items;
}

function get_autolist_for_taxonomy( $args ) {
    $query = apply_filters( 'autolist_query', array(
        'suppress_filters' => false,
        'post_type'        => 'any',
        'posts_per_page'   => $args['number'],
        'no_found_rows'    => true,
        'tax_query'        => array(
            array(
                'taxonomy' => $args['taxonomy'],
                'terms'    => array( $args['term_id'] ),
            )
        )
    ), 'taxonomy', $args );
    return get_autolist( $query, $args );
}

function get_autolist_for_post_parent( $args ) {
    $query = apply_filters( 'autolist_query', array(
        'suppress_filters' => false,
        'post_type'        => $args['post_type'],
        'posts_per_page'   => $args['number'],
        'no_found_rows'    => true,
        'post_parent'      => $args['post_parent'],
    ), 'post_parent', $args );
    return get_autolist( $query, $args );
}

function get_autolist_for_archive( $args ) {
    $query = apply_filters( 'autolist_query', array(
        'suppress_filters' => false,
        'post_type'        => $args['post_type'],
        'posts_per_page'   => $args['number'],
        'no_found_rows'    => true,
    ), 'archive', $args );
    return get_autolist( $query, $args );
}

function get_autolist( $query, $args ) {
    $autolist = get_posts( $query );
    $vars = array( 'parent' => $args['parent']->ID, 'count' => $args['count'] + 1 );
    array_walk( $autolist, 'willy_format_as_menu_item', $vars );
    return $autolist;
}

function willy_format_as_menu_item( $p, $k, $vars ) {
    $p->post_content     = '';
    $p->post_excerpt     = '';
    $p->menu_item_parent = $vars['parent'];
    $p->type             = 'post_type';
    $p->object_id        = $p->ID;
    $p->url              = get_permalink( $p );
    $p->title            = get_the_title( $p );
    $p->classes          = array( 'sub-elem-auto');
    $p->menu_order       = $vars['count'] + $k;
    return $p;
}
HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.