WP搜索页面的帖子根据帖子类型计算条件显示

问题描述

我正在尝试根据帖子类型在搜索页面上有条件地显示帖子数(帖子数)。

我正在寻找这样的东西:

add_action( 'pre_get_posts',function ( $query ) {
  if( ! is_admin() && $query->is_search() && $query->is_main_query() && is_post_type == 'MY_POST_TYPE' ) {
    $query->set( 'posts_per_page',1 );
  };
} );

我可以使用is_post_type == 'MY_POST_TYPE'来指定帖子类型的地方...我一直在寻找,但是找不到答案...这有点麻烦,因为它听起来像是一项基本功能。 ..有什么想法吗?

编辑1: 像这样,根据帖子类型显示不同数量的帖子

add_action( 'pre_get_posts',function ( $query ) {
if( ! is_admin() && $query->is_search() && $query->is_main_query() && is_post_type == 'MY_POST_TYPE_1' ) {
$query->set( 'posts_per_page',1 );
} elseif ( ! is_admin() && $query->is_search() && $query->is_main_query() && is_post_type == 'MY_POST_TYPE_2' ) {
$query->set( 'posts_per_page',10 );
};
} );  

解决方法

要基于查询CPT添加其他条件查询参数,我们可以像执行操作一样使用pre_get_posts钩子来做到这一点。

检查查询是否针对CPT

我们将创建一个自定义函数,该函数将挂接到该操作中,并检查$query是否包含CPT,如果存在则添加额外的args。您也想出了,这将起作用:

add_action( 'pre_get_posts','add_cpt_query_args');

function add_cpt_query_args( $query ) {
    // If this isn't the main search query on the site,then do nothing.
    if( is_admin() || !$query->is_search() || !$query->is_main_query() )
        return;
    // Check if the query is for any of our CPTs
    if (in_array ( $query->get( post_type'),array('YOUR_CPT_SLUG','ANOTHER_CPT') ) ){
        // set the args for this CPT
        $query->set( 'posts_per_page',1 );
        $query->set( 'orderby','rand' );
    }
}

检查多个CPT并使用不同的查询Args

由于要对多个CPT进行此操作并为它们提供不同的参数(例如posts_per_page),因此您必须在上面的代码中为每个CPT添加单独的if

一种更灵活和可维护的方法是使用数组将每个CPT的所有查询参数信息保留在数组中。这意味着:

  • 我们可以简单地循环遍历以使用添加查询参数-无需为要检查的每个CPT添加额外的if检查
  • 我们可以为每个CPT添加所需数量的查询arg(例如pages_per_postorder_by等),每个CPT可以具有不同的arg,而不必对其进行硬编码插入代码,或手动检查我们是否有相应的值。

我们可以使用此代码进行操作-下面详细说明了其工作原理 (注意-这未经测试,但是基本的逻辑就在那里!):

add_action( 'pre_get_posts','add_cpt_query_args');

function add_cpt_query_args( $query ) {

    // If this isn't the main search query on the site,then do nothing.
    if( is_admin() || !$query->is_search() || !$query->is_main_query() )
        return;

    // As you want to do this for multiple CPTS,a handy way to do this is set up all the info in an array
    $CPT_args['qcm'] = array('posts_per_page'=> 1,'orderby' => 'rand');
    $CPT_args['anotherCPT'] = array('posts_per_page'=> 5,'orderby' => 'date','order => 'ASC'');

    // Now check each CPT in our array to see if this query is for it
    foreach ($CPT_args as $cpt => $query_args ){
        if (in_array ( $query->get( post_type'),array($cpt) ) ){

            // this query is for a CPT in our array,so add our query args to the query
            foreach ($query_args as $arg => $value )
                $query->set( $arg,$value );
         }
    }
}

这是如何工作的

1。检查这是否是主站点上的主要搜索查询-如果不是(并且我们没有其他条件),最干净的方法就是在此时简单地结束该函数,那么我们就不尝试在if

中保留大量代码
if( is_admin() || !$query->is_search() || !$query->is_main_query() )
    return;

2。在数组中设置CPT参数-当您要对多个CPT执行此操作时,最简单的方法是将所有信息存储在数组中,我们可以将其简单地循环使用。

  • 在此示例中,我们将使用名为$CPT_args的数组,并为每个要检查的CPT添加一个条目,并以CPT名称为键。
  • 我们将使用另一个数组作为值,这会将您要添加到此CPT的$query的所有参数,例如
    $CPT_args['qcm'] = array('posts_per_page'=> 1,'orderby' => 'rand');

使用此数组可将所有args信息保存在一个地方,并且可以轻松添加或删除更多的CPT条件,而不会影响影响查询的主代码。


3。通过遍历我们的数组并检查$query数组中的键对查询post_type进行检查,以检查$CPT_args是否用于任何CPTS

foreach ($CPT_args as $cpt => $query_args ){
    if (in_array ( $query->get( post_type'),array($cpt) ) ){
        ... 
    }
}


4。如果此查询针对该CPT,则将CPT的查询参数添加到$query 。我们可以简单地浏览我们的args数组并将它们添加到$query中。

    foreach ($queryargs as $arg => $value )
        $query->set( $arg,$value );