WP_LIST_PAGES()排除类别

时间:2020-01-19 作者:Phil

我尝试将此添加到一个类似的旧帖子中,但没有得到回应,所以我将其作为一个新问题发布。

我有一个基于页面的大型网站,我正在工作。因为它主要是页面驱动的,所以我使用了一个函数来允许页面上的类别和标记。我想知道是否有办法使用wp\\u list\\u pages()函数排除类别。这将允许我输入一个id或slug,而不是每次有新的页面要排除时,都用新的页面id更新它。

更具体地说,我正在使用以下函数,其中使用了wp\\u list\\u pages()函数。

function wpb_list_child_pages() { 

global $post; 

if ( is_page() && $post->post_parent )

    $childpages = wp_list_pages( \'sort_column=menu_order&title_li=&child_of=\' . $post->post_parent . \'&echo=0\' );
else
    $childpages = wp_list_pages( \'sort_column=menu_order&title_li=&child_of=\' . $post->ID . \'&echo=0\' );

if ( $childpages ) {

    $string = \'<ul>\' . $childpages . \'</ul>\';
}

return $string;

}

add_shortcode(\'wpb_childpages\', \'wpb_list_child_pages\');
该函数可在此处找到:https://www.wpbeginner.com/wp-tutorials/how-to-display-a-list-of-child-pages-for-a-parent-page-in-wordpress/

非常感谢。

1 个回复
最合适的回答,由SO网友:Tim Elsass 整理而成

我认为最适合您的解决方案就是使用您自己的查询。因为您已经修改了页面,使其具有类别和标记分类法wp_list_pages 不支持这样排除参数。您可以获得分配给每个类别的所有页面ID的数组,但您需要为此编写一个查询。您最好只做一次,忘记使用wp_list_pages.

就实现而言,上面的代码给了我错误,因为$string 最终可能会导致未定义并尝试返回。下面是一个工作示例,我认为它实现了您的目标:

// functions.php

// These hooks are only here as I wasn\'t sure if you actually meant that you were adding cat/tag to pages as there wasn\'t any code provided referencing that.
add_action( \'init\', \'wpse356728_add_tags_cats_pages\' );
add_action( \'pre_get_posts\', \'wpse356728_tags_cats_update_queries\' );

/**
 * Register the tags and cats tax for pages.
 */
function wpse356728_add_tags_cats_pages() {
    register_taxonomy_for_object_type( \'post_tag\', \'page\' );
    register_taxonomy_for_object_type( \'category\', \'page\' );  
}

/**
 * Ensure pages are added to any queries for tags and cats.
 */
function wpse356728_tags_cats_update_queries( $wp_query ) {
    if ( $wp_query->get( \'tag\' ) ) {
        $wp_query->set( \'post_type\', \'any\' );
    }
    if ( $wp_query->get( \'category_name\' ) ) {
        $wp_query->set( \'post_type\', \'any\' );
    }
}

/**
 * Create list of pages that are parents with optional exclude
 * pages by category name.
 * 
 * @param array $cats Array of category names to exclude from query.
 */
function wpse356728_list_child_pages( $cats = [] ) { 
    global $post;

    $current_ID = $post->ID;

    if ( is_page() && $post->post_parent ) {
        $child_of = $post->post_parent;
    } else {
        $child_of = $current_ID;
    }

    // Get the category IDs for passed in category names for query.
    $cats = ( array ) $cats;
    $cats = array_map( \'get_cat_ID\', $cats );

    $args = [
        \'post_type\'      => \'page\',
        \'posts_per_page\' => -1,
        \'post_parent\'    => $child_of,
        \'order\'          => \'DESC\',
        \'orderby\'        => \'menu_order\',
        \'category__not_in\' => $cats,
    ];

    $parent = new WP_Query( $args );

    if ( $parent->have_posts() ) : ?>
    <ul>
        <?php while ( $parent->have_posts() ) : $parent->the_post(); ?>
            <?php
                $current = function( $output ) use ( $current_ID ) {
                    return get_the_ID() === $current_ID ? $output : \'\';
                };
            ?>
                <li class="page_item page_item-<?php the_ID(); echo $current( \' current_page_item\' ); ?>">
                    <a href="<?php the_permalink(); ?>" <?php echo $current( \'aria-current="page"\' ); ?>><?php the_title(); ?></a>
                </li>
        <?php endwhile; ?>
    </ul>
    <?php endif; wp_reset_postdata();
}

方法wpse356728_list_child_pages 这才是你应该看到的。而不是使用wp_list_pages 正如您所做的那样,这显示了如何从几乎相同的标记的WP\\U查询中获取输出,并允许您传入要在返回的查询列表中排除页面的类别名称。这将提供更大的灵活性,因为您可以将许多其他参数传递给查询。

用法:

// page.php
<?php wpse356728_list_child_pages( [ \'sports\', \'animals\', \'movies\' ] ); ?>
上述代码将从查询中省略体育、动物和电影类别。您可以修改的输出wpse356728_list_child_pages 将其作为字符串返回,并在必要时创建一个短代码。在我的测试主题中,我只使用了page.php 并将代码添加到functions.php 而是这样:

// functions.php

add_action( \'theme_name_after_page_content\', function() {
    $cats_to_exclude = [ \'sports\', \'animals\', \'movies\' ];
    wpse356728_list_child_pages( $cats_to_exclude );
} );