提前重定向
首先,你的重定向函数应该提前挂接:你不依赖那里的查询变量,所以你可以使用
init
挂钩:
function search_redirect() {
if (!empty($_GET[\'s\'])) {
$home = trailingslashit(home_url(\'catalog-of-work\'));
wp_safe_redirect($home.urlencode(get_query_var(\'s\')));
exit();
}
}
add_action(\'init\', \'search_redirect\');
原因是这将更早地重定向请求,节省大量处理。
正确设置查询变量现在,您需要告诉WordPress当URL/catalog-of-work
被访问时,必须考虑搜索请求。
function custom_search_query_var($do, $wp) {
$path = trim(parse_url(esc_url_raw(add_query_arg([])), PHP_URL_PATH), \'/\');
$home_path = trim(parse_url(esc_url_raw(home_url()), PHP_URL_PATH), \'/\');
$home_path and $path = trim(substr($path, strlen($home_path)), \'/\');
if (strpos($path, \'catalog-of-work\') === 0) {
$wp->query_vars[\'s\'] = trim(substr($path, 15), \'/\');
$do = false;
}
return $do;
}
add_action(\'do_parse_request\', \'custom_search_query_var\', 10, 2);
在上面的代码中需要注意以下几点:
我用过do_parse_request
钩子代替parse_request
. 这允许我在URL/catalog-of-work
已访问。由于处理查询变量的过程可能很慢,因此这可以提高页面性能确定当前URL的我的逻辑使用add_query_arg
而不是直接访问$_SERVER
. 这更好,因为该函数处理一些边缘情况我的逻辑处理的情况是,您的主页URL类似example.com/wp
而不是example.com
. 由于主页URL可以很容易地更改,这确保了该功能更稳定,并且可以在不同的情况下工作我使用的代码在$wp->query_vars
大堆$wp
是的当前实例WP
通过的类do_parse_request
钩这样做更好,原因有二:避免直接访问全局变量,将变量设置为全局变量$wp_query
在上不可靠do_parse_request
(均未打开parse_request
你用过)因为挂钩以前发生过$wp_query
已处理,并且可能仍会发生一些重置,删除s
通过将查询变量设置为$wp
对象,它将注意将变量传递给$wp_query
.
阻止404做我描述的事情,拥有404模板不会影响任何事情,因为WordPressnot 为搜索查询设置404状态。
但是,我的代码(就像你的代码一样,至少是你发布的代码)不会作用于模板,因此默认情况下,WordPress将加载search.php
.
您的search.php
模板(或您正在使用的模板)检查have_posts()
并在没有帖子时加载404模板(如果找到)。
这取决于你使用的主题。
例如,主题Twenty15包含如下内容:
<?php if ( have_posts() ) : ?>
// ... redacted loop code here...
else :
// If no content, include the "No posts found" template.
get_template_part( \'content\', \'none\' );
endif;
?>
如果您的主题包含类似的内容,则可以在没有帖子的情况下加载404模板,这在搜索查询为空时发生。如果这是一个问题,你应该编辑你的搜索模板(或者如果主题是第三方或核心主题,你应该创建一个child theme) 让搜索模板根据您的需要处理没有帖子的情况。