如何在WordPress的主查询中添加自定义文章类型

WordPress默认是不会将自定义文章类型加入主查询的。

主查询(Main Query)

WordPress中的查询是 WP_Query 类的实例。主查询是负责处理每个请求的查询。此查询由WordPress自动创建和维护。

在各请求的过程中,WordPress将URL翻译成一组查询变量,用这些变量配置主查询并获取结果。主查询被保存在全局变量 $wp_the_query 中。

除了主查询之外的其他查询被称为“自定义查询”或“辅助查询”。

问题

WordPress默认不会将自定义文章类型添加到主查询中,所以如果你在自定义文章类型中插入了一条数据,这条数据是不会出现在主页、归档页等页面上的。

为了验证这个问题,用下面的代码来注册一个叫“Book”的自定义文章类型,创建一本新书,然后访问主页。这本书的信息是不会出现的。

/*
 * Registers the custom post type Book.
 */
function ns_register_book_cpt(){
    
    // See all possible labels in the PHPDoc of the function get_post_type_labels
    $labels = array(
       'name'                  => __('Books', 'ns'),
       'singular_name'         => __('Book', 'ns'),
       'menu_name'             => __('Books', 'ns'),
       'all_items'             => __('All Books', 'ns'),
       'add_new'               => __('Add New', 'ns'),
       'add_new_item'          => __('Add New Book', 'ns'),
       'edit_item'             => __('Edit Book', 'ns'),
       'new_item'              => __('New Book', 'ns'),
       'view_item'             => __('View Book', 'ns'),
       'view_items'            => __('View Books', 'ns'),
       'search_items'          => __('Search Books', 'ns'),
       'not_found'             => __('No books found.', 'ns'),
       'not_found_in_trash'    => __('No books found in Trash.', 'ns'),
       'archives'              => __('Book Archives', 'ns'),
       'filter_items_list'     => __('Filter books list', 'ns'),
       'items_list_navigation' => __('Books list navigation', 'ns'),
       'items_list'            => __('Books list', 'ns')
    );
    
    // See all possible attributes in the PHPDoc of the function register_post_type
    $args = array(
        'label'                 => __('Books', 'ns'),
        'labels'                => $labels, 
        'public'                => true,
        'exclude_from_search'   => false,
        'publicly_queryable'    => true,
        'show_ui'               => true,
        'show_in_nav_menus'     => true,
        'show_in_menu'          => true,
        'show_in_admin_bar'     => true,
        'hierarchical'          => false,
        'supports'              => array('title', 'editor', 'author'), 
        'taxonomies'            => array('post_tag'),
        'has_archive'           => true, 
        'rewrite'               => array('slug' => 'books'),
        'query_var'             => 'book'
    );
    
    register_post_type('ns_book_cpt', $args);
}
add_action('init', 'ns_register_book_cpt', 10, 0);

解决方案

使用“ pre_get_posts ”操作将自定义post类型添加到主查询。 步骤如下:

  1. 检查所需的查询是否正在被处理
  2. 用希望出现在查询中的文章类型填充数组
  3. 设置“post_type”查询变量

以下代码会将自定义文章类型 Book 添加到主页的主查询中

/*
 * Sets the post types that can appear on the homepage.
 */
function ns_set_home_post_types($query){
    
    $is_target_query = 
            !is_admin() && 
            $query->is_main_query() && 
            $query->is_home;

    if($is_target_query){
        $target_types = array('post', 'ns_book_cpt');
        $query->set('post_type', $target_types);
    }
}
add_action('pre_get_posts', 'ns_set_home_post_types', 10, 1);

当显示除文章类型归档页之外的其他归档页面时,下面的代码会将自定义文章类型Book添加到主查询中。如果显示的是文章类型归档页,那么修改“post_type”查询变量没有任何意义。

/*
 * Sets the post types that can appear on archive pages.
 */
function ns_set_archive_post_types($query){
    
    // We cannot use 'is_archive' here because post type archives should not be included
    $is_target_query = 
            !is_admin() && 
            $query->is_main_query() && 
            ($query->is_date || 
            $query->is_author || 
            $query->is_category || 
            $query->is_tag || 
            $query->is_tax); 
            
    if($is_target_query){
        $target_types = array('post', 'ns_book_cpt');
        $query->set('post_type', $target_types);
    }
}
add_action('pre_get_posts', 'ns_set_archive_post_types', 10, 1);

源代码

本教程中用到的源代码可以在这里下载

为您推荐

发表评论

邮箱地址不会被公开。 必填项已用*标注