我有一个自定义标签搜索功能,允许人们搜索多个标签以返回相关帖子。表示他们希望看到标记为“Wordpress”和“Tutorials”的帖子。我正在使用template_include
过滤器,如下所示:
public static function template_redirect( $template ) {
if( isset($_GET[\'tag-search\']) )
{
$template = locate_template( array(
\'search.php\',
\'archive.php\',
\'index.php\'
));
}
return $template;
}
the
tag-search
变量保存分类法的名称,我检查它是否已设置,从而指示正在执行搜索。
在这一点上template
解析为搜索。php,就像它应该的那样。所以这很好。
在pre_get_posts
操作I添加atax_query
要将返回的帖子修改为仅选定的标签,我设置is_search
为真,以及is_home
为false。这是我的pre_get_posts
措施:
public static function pre_get_posts($query) {
if( !isset($_GET[\'tag-search\']) || !isset($_GET[\'terms\']) ) return $query;
if( strtolower( $_GET[\'method\'] ) == \'and\' )
{
$query->set( \'tax_query\', array(
array(
\'taxonomy\' => $_GET[\'tag-search\'],
\'field\' => \'slug\',
\'terms\' => explode(\',\', $_GET[\'terms\']),
\'operator\' => \'AND\'
)
) );
}
else
{
$query->set( \'tax_query\', array(
array(
\'taxonomy\' => $_GET[\'tag-search\'],
\'field\' => \'slug\',
\'terms\' => explode(\',\', $_GET[\'terms\'])
)
) );
}
$query->is_search = true;
$query->is_home = false;
return $query;
}
然而,当我执行搜索时,body类是“home”,所有
is_home
和
is_front_page
条件是
true, 他们不应该这样,因为我只是特别声明我希望这是一个搜索模板,对吗?
我知道这是可以做到的-当我添加&s
对于查询字符串,它按其应该的方式工作-尽管这样有点难看。有什么见解吗?
最合适的回答,由SO网友:gmazzap 整理而成
您的问题是没有重置所有需要的查询变量,例如WP_Query::$is_page
, WP_Query::$is_single
和WP_Query::$is_archive
.
还要注意的是\'pre_get_posts\'
为所有查询(主查询和辅助查询)激发,因此您应该检查是否正在处理主查询。
最后,当您从$_GET
你应该在使用前对其进行消毒,一个好方法是filter_input()
或filter_input_array()
.
您的方法应该如下所示:
public static function pre_get_posts($query)
{
$data = filter_input_array(INPUT_GET, array(
\'tag-search\' => FILTER_SANITIZE_STRING,
\'terms\' => FILTER_SANITIZE_STRING,
\'method\' => FILTER_SANITIZE_STRING,
));
if( $query->is_main_query() && !empty($data[\'tag-search\']) && !empty($data[\'terms\']) ) {
$query->init(); // this resets ALL vars
$query->is_search = true;
// set tax query array
$tax_query = array(
\'taxonomy\' => $data[\'tag-search\'],
\'field\' => \'slug\',
\'terms\' => explode(\',\', $data[\'terms\']),
);
// is AND method?
if( strtolower( $data[\'method\'] ) === \'and\' ) {
$tax_query[\'operator\'] = \'AND\';
}
// set tax query
$query->set( \'tax_query\', array($tax_query) );
}
}
这样做你就这样做了
not 需要筛选模板(以便您可以删除
template_redirect()
方法):
search.php
将由WordPress加载,因为它将正确地将查询识别为搜索。
PS:\'pre_get_post\'
是一个action, 不是过滤器,所以你don\'t 如果修改查询,也不需要返回查询。
SO网友:chifliiiii
请尝试以下操作:
public static function pre_get_posts($query) {
if( !isset($_GET[\'tag-search\']) || !isset($_GET[\'terms\']) ) return $query;
if ( ! is_admin() && $query->is_main_query() ) {
if( strtolower( $_GET[\'method\'] ) == \'and\' )
{
$query->set( \'tax_query\', array(
array(
\'taxonomy\' => $_GET[\'tag-search\'],
\'field\' => \'slug\',
\'terms\' => explode(\',\', $_GET[\'terms\']),
\'operator\' => \'AND\'
)
) );
}
else
{
$query->set( \'tax_query\', array(
array(
\'taxonomy\' => $_GET[\'tag-search\'],
\'field\' => \'slug\',
\'terms\' => explode(\',\', $_GET[\'terms\'])
)
) );
}
$query->set(\'s\', \'\' );
$query->is_search = true;
$query->is_home = false;
}
return $query;
}
我添加了一些额外的检查,并以一种不那么难看的方式添加了“s”