web-dev-qa-db-fra.com

Aucun lien sur une page vide dans wp_list_pages

J'utilise actuellement

<?php wp_list_pages( 'post_type=region&title_li=' ); ?>

Pour obtenir la liste hiérarchique de mes régions personnalisées. Ça fonctionne parfaitement. J'ai eu ceci:

  • L'Europe 
    • Belgique
    • France
  • Asie
    • Chine

Avec un lien sur chaque article. MAIS certaines pages n'ont pas de contenu. C'est juste là pour créer la hiérarchie. Dans cet exemple, ASIE n'a pas de contenu.

Je voudrais donc un moyen de créer cette liste de menus, mais si la page n'a pas de contenu -> pas de lien pour cet élément.

Donc, je suppose, je dois utiliser un autre moyen que wp_list_pages. Mais lequel ?

Pouvez-vous m'aider ?

Je vous remercie !

2
Emersion

wp_list_pages() utilise un marcheur nommé Walker_Page pour afficher le résultat, ce qui peut être remplacé.

Vous trouverez ci-dessous une version personnalisée de Walker_Page::start_el(). Le code a d'abord été copié à partir du noyau, puis une vérification simple a été ajoutée avant la sortie du lien. Si un message ne contient aucun contenu, le titre est entouré d'une balise <span> plutôt que d'un <a>.

Ici, la modification est mise en évidence:

    ...
    // Modification: If a posts content is empty, do not link the item. Instead use a span tag to wrap the text.
    $maybe_link_item = empty( $page->post_content ) ? '<li class="%s"><span class="no-link">%3$s%4$s%5$s</span>' : '<li class="%s"><a href="%s">%s%s%s</a>';

    $output .= $indent . sprintf(
        $maybe_link_item, // Modification: Using this variable instead of '<li class="%s"><a href="%s">%s%s%s</a>'
        $css_classes,
        get_permalink( $page->ID ),
        $args['link_before'],
        /** This filter is documented in wp-includes/post-template.php */
        apply_filters( 'the_title', $page->post_title, $page->ID ),
        $args['link_after']
    );
    ...

Voici le marcheur complet:

class WPSE_Walker_Page extends Walker_Page {
    // Copied from Walker_Page::start_el() core version v4.7.4.
    /**
     * Outputs the beginning of the current element in the tree.
     *
     * @see Walker::start_el()
     * @since 2.1.0
     * @access public
     *
     * @param string  $output       Used to append additional content. Passed by reference.
     * @param WP_Post $page         Page data object.
     * @param int     $depth        Optional. Depth of page. Used for padding. Default 0.
     * @param array   $args         Optional. Array of arguments. Default empty array.
     * @param int     $current_page Optional. Page ID. Default 0.
     */
    public function start_el( &$output, $page, $depth = 0, $args = array(), $current_page = 0 ) {
        if ( isset( $args['item_spacing'] ) && 'preserve' === $args['item_spacing'] ) {
            $t = "\t";
            $n = "\n";
        } else {
            $t = '';
            $n = '';
        }
        if ( $depth ) {
            $indent = str_repeat( $t, $depth );
        } else {
            $indent = '';
        }

        $css_class = array( 'page_item', 'page-item-' . $page->ID );

        if ( isset( $args['pages_with_children'][ $page->ID ] ) ) {
            $css_class[] = 'page_item_has_children';
        }

        if ( ! empty( $current_page ) ) {
            $_current_page = get_post( $current_page );
            if ( $_current_page && in_array( $page->ID, $_current_page->ancestors ) ) {
                $css_class[] = 'current_page_ancestor';
            }
            if ( $page->ID == $current_page ) {
                $css_class[] = 'current_page_item';
            } elseif ( $_current_page && $page->ID == $_current_page->post_parent ) {
                $css_class[] = 'current_page_parent';
            }
        } elseif ( $page->ID == get_option('page_for_posts') ) {
            $css_class[] = 'current_page_parent';
        }

        /**
         * Filters the list of CSS classes to include with each page item in the list.
         *
         * @since 2.8.0
         *
         * @see wp_list_pages()
         *
         * @param array   $css_class    An array of CSS classes to be applied
         *                              to each list item.
         * @param WP_Post $page         Page data object.
         * @param int     $depth        Depth of page, used for padding.
         * @param array   $args         An array of arguments.
         * @param int     $current_page ID of the current page.
         */
        $css_classes = implode( ' ', apply_filters( 'page_css_class', $css_class, $page, $depth, $args, $current_page ) );

        if ( '' === $page->post_title ) {
            /* translators: %d: ID of a post */
            $page->post_title = sprintf( __( '#%d (no title)' ), $page->ID );
        }

        $args['link_before'] = empty( $args['link_before'] ) ? '' : $args['link_before'];
        $args['link_after'] = empty( $args['link_after'] ) ? '' : $args['link_after'];

        // Modification: If a posts content is empty, do not link the item. Instead use a span tag to wrap the text.
        $maybe_link_item = empty( $page->post_content ) ? '<li class="%s"><span class="no-link">%3$s%4$s%5$s</span>' : '<li class="%s"><a href="%s">%s%s%s</a>';

        $output .= $indent . sprintf(
            $maybe_link_item, // Modification: Using this variable instead of '<li class="%s"><a href="%s">%s%s%s</a>'
            $css_classes,
            get_permalink( $page->ID ),
            $args['link_before'],
            /** This filter is documented in wp-includes/post-template.php */
            apply_filters( 'the_title', $page->post_title, $page->ID ),
            $args['link_after']
        );

        if ( ! empty( $args['show_date'] ) ) {
            if ( 'modified' == $args['show_date'] ) {
                $time = $page->post_modified;
            } else {
                $time = $page->post_date;
            }

            $date_format = empty( $args['date_format'] ) ? '' : $args['date_format'];
            $output .= " " . mysql2date( $date_format, $time );
        }
    }
}

Pour utiliser le nouveau lecteur, ajoutez-le au functions.php de votre thème ou à un plug-in, puis modifiez l'appel en wp_list_pages() pour qu'il utilise notre nouveau lecteur personnalisé:

    wp_list_pages( [
        'post_type' => 'region',
        'walker'    => new WPSE_Walker_Page(),
        'title_li'  => '',
    ] );
1
Dave Romsey