web-dev-qa-db-fra.com

Comment puis-je peupler de manière dynamique wp_nav_menu à partir d'une taxonomie personnalisée?

Je sais que cette question a été posée sous différentes formes. Mais d'après ce que je peux dire à partir des recherches sur Google et SE/WP, il n'a jamais été répondu de manière satisfaisante.

Disons que j'ai une taxonomie clubs et un type de message personnalisé person .

Sur chaque page taxonomy-club.php, j’affiche tous les personnes qui sont membres de cette club .

Mais Je souhaite obtenir un effet similaire dans mes menus:

wp_nav_menu
|
|--Everyone
|  \
|  |- Mr Verlaine
|  |- Mr Lloyd
|  |- Mr Osterberg 
|  |- Mr Williamson    
|
|--Snooker Club
|  \ 
|  |- Mr Osterberg 
|  |- Mr Williamson
|
|--Golf Club
|  \
|  |- Mr Verlaine
|  |- Mr Lloyd

Si possible, j'aimerais que la fonctionnalité de surlignage de la fonction wp_nav_menu() soit affichée dans mes menus.

J'ai expérimenté ceci:

add_filter('wp_nav_menu_items','add_terms');

function add_terms($items) {
$items .= '<li>' . wp_list_categories( array(
    'taxonomy' => 'clubs', 
    'title_li' => 'Clubs') ) 
     . '</li>';
return $items;
}

mais il ne remplit pas les sous-menus avec les noms des personnes, et il n'a pas cette bonté nav_menu css-class.

Dois-je créer un <li> plus compliqué en interrogeant les articles dans chaque terme de la taxonomie, puis en le collant, et c'est tout pour moi? Ou étendre le walker intégré (cela me donnera-t-il les avantages de wp_nav_menu?)

Ou autre chose...

Merci!

6
djb

Je voudrais aller pour le menu de navigation personnalisé Walker ...

//define the custom post type and custom taxonomy
define("MENU_CPT", "people");
define("MENU_CT", "club");

//custom function for selecting posts based on a term
function get_posts_by_term($term_id, $post_type=MENU_CPT, $taxonomy=MENU_CT) {
    $args = array(
        'posts_per_page' => -1,
        'post_type' => $post_type,
        'tax_query' => array(
            array(
                'taxonomy' => $taxonomy,
                'field' => 'id',
                'terms' => $term_id
            )
        )
    );                  
    return get_posts( $args );
}

//custom nav menu walker class
class Custom_Walker_Nav_Menu extends Walker_Nav_Menu {
    /**
     * Display array of elements hierarchically.
     *
     * It is a generic function which does not assume any existing order of
     * elements. max_depth = -1 means flatly display every element. max_depth =
     * 0 means display all levels. max_depth > 0  specifies the number of
     * display levels.
     *
     * @since 2.1.0
     *
     * @param array $elements
     * @param int $max_depth
     * @return string
     */
    function walk( $elements, $max_depth) {

        $args = array_slice(func_get_args(), 2);
        $output = '';

        if ($max_depth < -1) //invalid parameter
            return $output;

        if (empty($elements)) //nothing to walk
            return $output;

        $id_field = $this->db_fields['id'];
        $parent_field = $this->db_fields['parent'];

        // flat display
        if ( -1 == $max_depth ) {
            $empty_array = array();
            foreach ( $elements as $e )
                $this->display_element( $e, $empty_array, 1, 0, $args, $output );
            return $output;
        }

        /*
         * need to display in hierarchical order
         * separate elements into two buckets: top level and children elements
         * children_elements is two dimensional array, eg.
         * children_elements[10][] contains all sub-elements whose parent is 10.
         */
        $top_level_elements = array();
        $children_elements  = array();
        foreach ( $elements as $e) {
            if ( 0 == $e->$parent_field ) 
            {
                $top_level_elements[] = $e;
                if ( $e->type=='taxonomy' && $e->object == MENU_CT ) {

                    $taxonomy_posts = get_posts_by_term($e->object_id);

                    foreach ( $taxonomy_posts as $tax_post ) {                      
                        $tax_post = wp_setup_nav_menu_item($tax_post);
                        $tax_post->post_type = 'nav_menu_item';
                        $tax_post->menu_item_parent = $e->$id_field;
                        $tax_post->object = 'custom';
                        $tax_post->type = 'custom';
                        $tax_post->ID = $e->$id_field.$tax_post->ID;
                        $children_elements[ $e->$id_field ][] = $tax_post; 
                        $children_elements_classes[] = $tax_post; 
                    }
                }
            }
            else
            {
                $children_elements[ $e->$parent_field ][] = $e;
            }
        }

        /*
         * when none of the elements is top level
         * assume the first one must be root of the sub elements
         */
        if ( empty($top_level_elements) ) {

            $first = array_slice( $elements, 0, 1 );
            $root = $first[0];

            $top_level_elements = array();
            $children_elements  = array();
            foreach ( $elements as $e) {
                if ( $root->$parent_field == $e->$parent_field )
                {
                    $top_level_elements[] = $e;
                    if ( $e->type=='taxonomy' && $e->object == MENU_CT ) {

                        $taxonomy_posts = get_posts_by_term($e->object_id);

                        foreach ( $taxonomy_posts as $tax_post ) {                      
                            $tax_post = wp_setup_nav_menu_item($tax_post);
                            $tax_post->post_type = 'nav_menu_item';
                            $tax_post->menu_item_parent = $e->$id_field;
                            $tax_post->object = 'custom';
                            $tax_post->type = 'custom';
                            $tax_post->ID = $e->$id_field.$tax_post->ID;
                            $children_elements[ $e->$id_field ][] = $tax_post;
                            $children_elements_classes[] = $tax_post; 
                        }
                    }
                }
                else
                {
                    $children_elements[ $e->$parent_field ][] = $e;
                }
            }
        }

        //assing the classes to our dynamically populated posts
        if ( $children_elements_classes )
            _wp_menu_item_classes_by_context($children_elements_classes);

        foreach ( $top_level_elements as $e )
            $this->display_element( $e, $children_elements, $max_depth, 0, $args, $output );

        /*
         * if we are displaying all levels, and remaining children_elements is not empty,
         * then we got orphans, which should be displayed regardless
         */
        if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) {
            $empty_array = array();
            foreach ( $children_elements as $orphans )
                foreach( $orphans as $op )
                    $this->display_element( $op, $empty_array, 1, 0, $args, $output );
         }

         return $output;
    }
}

... vous pouvez maintenant l'utiliser dans wp_nav_menu function:

wp_nav_menu( array( 'theme_location' => 'primary', 'walker' => new Custom_Walker_Nav_Menu ) );

Lorsque vous insérez le terme de la taxonomie définie dans votre menu, il est automatiquement renseigné par les publications (noms de personnes) du type de publication personnalisé défini pour une taxonomie particulière.

3
Ján Bočínec