我试图加载/利用现有的页面模板(templates/results.php),同时使用;s“;(搜索)查询参数。例如:示例。com/结果?s=lorem
目前,这导致404。
我有一个过滤器template_includes
, 然而,该页面似乎已经是;“已决定”;在挂钩/过滤器之前(is_search()
, is_page(\'results\')
均为false),然后加载模板。我可以根据一些其他参数加载模板文件,但之后我必须将标题和其他内容设置为远离404页面。
这个pagename
和s
字段在global $wp_query
\'的原始查询变量,因此它只是一个;“决定”;在命中模板之前,查询实际上是什么。
可以显示自定义帖子类型的筛选帖子集的用例;列表;。Listings archive已经显示了列表,并自动过滤为;“打开”;,并可根据其分类进行筛选,以及;s“;用于任何搜索。我会让结果页面做同样的事情,能够提取与其归档对应的相同的可选查询参数。
如何在仍使用内置模板的情况下加载页面并使用现有页面模板s
查询参数?
这answer\'s解决方案1提到将默认的“s”查询变量替换为自定义变量,旨在避免这种情况,希望在WordPress决定在结果页中搜索“s”字符串之前进行筛选/挂接。
当前如何使用页面/查询:
Template file:
<?php
// get_header() and the_post() related parts have already been called in the main template file.
// Temporary query to replace the main one so we can utilise pagination, etc.
global $post;
global $wp_query;
$listing_results_query = new WP_Query( [
\'listing_type\' => get_query_var( \'listing_type\' ),
\'pricing\' => get_query_var( \'pricing\' ),
\'s\' => get_query_var( \'s\' ),
\'paged\' => get_query_var( \'paged\', 1 ),
\'post_type\' => \'listing\',
\'query_id\' => \'listing-results\',
\'listing_status_compare\' => \'!=\'
] );
$temp_query = $wp_query;
$wp_query = NULL;
$wp_query = $listing_results_query;
?>
<span>Various HTML and get_template_part() calls being used to load the archive</span>
<?php
// Reset main query object
$wp_query = NULL;
$wp_query = $temp_query;
?>
Hook/function file (equivalent of functions.php)我删去了一些检查/其他查询部分,以简化此处的操作。在调用此挂钩(pre\\u get\\u posts)时,
$query->is_404
已设置为
true
.
function wpse_390935_modify_listing_archive_query( $query ) {
$is_listing_archive_results = ! is_admin() && ( $query->query[\'query_id\'] ?? false ) === \'listing-results\';
if ( $is_listing_archive_results ) {
$page_no = $query->query[\'paged\'] ?? 1;
$listing_type = $query->query[\'listing_type\'] ?? \'\';
$pricing = $query->query[\'pricing\'] ?? \'\';
$search = $query->query[\'s\'] ?? \'\';
$status_compare = $query->query[\'listing_status_compare\'] ?? \'=\';
$meta_query = [];
// Search
if ( $search ) {
$query->set( \'s\', sanitize_text_field( $search ) );
}
// Other custom field/taxonomy query bits
}
}
add_action( \'pre_get_posts\', \'wpse_390935_modify_listing_archive_query\', 10, 1 );
最合适的回答,由SO网友:bosco 整理而成
自定义查询变量移动s
在显式请求页面时调用自定义查询变量应该足够简单:
function wpse390935_set_page_search_qv( $wp ) {
$qvs = $wp->query_vars;
if( empty( $qvs[\'s\'] ) || ( empty( $qvs[\'pagename\'] ) && empty( $qvs[\'page_id\'] ) ) )
return;
$wp->query_vars[\'page_search\'] = $qvs[\'s\'];
unset( $wp->query_vars[\'s\'] );
}
add_action( \'parse_query\', \'wpse390935_set_page_search_qv\' );
这可以防止它被分解到主查询中,而使它以后可以通过
get_query_var( \'page_search\' )
, 并继续将变量表示为
s
最终用户。
如果绝对需要保留在s
在内部,您可以使用一些黑客并删除s
来自请求的query_vars
使用parse_request
操作挂钩,然后在查询执行后再次添加它。
我在这里用了一节单身课s
挂钩之间的值。
class WPSE390935_Search_Param_Passthrough {
private static $instance = null;
private $search = \'\';
public static function get_instance() {
if( is_null( self::$instance ) )
self::$instance = new self();
return self::$instance;
}
private function __construct() {
add_action( \'parse_request\', [ $this, \'stash_query_var\' ], 2 );
}
public function is_page_search() {
if( is_admin() )
return false;
if( did_action( \'parse_request\' ) > 0 )
return ! empty( $this->search );
throw new Error( \'Too early to determine is_page_search() condition.\' );
}
public function restore_query_var() {
set_query_var( \'s\', $this->search );
}
public function stash_query_var( $wp ) {
$qvs = $wp->query_vars;
if( ( empty( $qvs[\'pagename\'] ) && empty( $qvs[\'page_id\'] ) ) || empty( $qvs[\'s\'] ) )
return;
$this->search = $qvs[\'s\'];
unset( $wp->query_vars[\'s\'] );
add_action( \'wp\', [ $this, \'restore_query_var\' ], 2 );
}
}
function is_page_search() {
return WPSE390935_Search_Param_Passthrough::get_instance()->is_page_search();
}
WPSE390935_Search_Param_Passthrough::get_instance();
我强烈建议不要将搜索值添加回主查询,而是在需要时从类中检索它。这样,主查询的查询变量的状态就不会歪曲主查询的实际情况。
为了达到类似的目的,我还提供了另一个条件谓词,其形式为is_page_search()
. 当你可以设置$wp_query->is_search = true
在restore_query_var()
方法,我会担心可能产生的任何副作用。无论是在核心还是任何插件中,都取决于核心谓词。