admin管理员组文章数量:1130349
I am trying to customize the search results for a generic search, but only if it's using the search.php template. I have other searches on my site, and I don't want this filter interfering with them. Everything works on the following code, except for is_page_template('search.php').
Once I enter that line of code as a condition, it just reverts to the normal search filtering, because my IF condition is failing. How do I only run my code if we're on the search.php page?
//Filter the search for only posts and parts
function SearchFilter($query)
{
if ($query->is_search && is_page_template('search')) {
$query->set('post_type', array('post', 'parts'));
$query->set('meta_key', 'Manufacturer');
$query->set('orderby', 'meta_value');
$query->set('order', 'ASC');
}
return $query;
}
add_filter('pre_get_posts', 'SearchFilter');
I am trying to customize the search results for a generic search, but only if it's using the search.php template. I have other searches on my site, and I don't want this filter interfering with them. Everything works on the following code, except for is_page_template('search.php').
Once I enter that line of code as a condition, it just reverts to the normal search filtering, because my IF condition is failing. How do I only run my code if we're on the search.php page?
//Filter the search for only posts and parts
function SearchFilter($query)
{
if ($query->is_search && is_page_template('search')) {
$query->set('post_type', array('post', 'parts'));
$query->set('meta_key', 'Manufacturer');
$query->set('orderby', 'meta_value');
$query->set('order', 'ASC');
}
return $query;
}
add_filter('pre_get_posts', 'SearchFilter');
Share
Improve this question
edited Jun 28, 2017 at 14:21
Johansson
15.4k11 gold badges44 silver badges80 bronze badges
asked Jun 28, 2017 at 14:15
Jordan CarterJordan Carter
2912 gold badges5 silver badges13 bronze badges
2
|
2 Answers
Reset to default 6Lets break it down step by step:
if ($query->is_search && is_page_template('search')) {
There are 3 problems here
is_page_template
search.php isn't a page template, that's not how the search template is loaded. So this won't work.
But if it did work, there's a new problem. Functions such as is_page_template etc rely on the main query, but we're in a pre_get_posts filter, you don't know if that query has been set yet, or if you're filtering that query or another.
So we need to:
- remove the
is_page_templatecheck, it doesn't do what you think it does - Add an
$query->is_main_query()check so the filter doesn't interfere with widgets and other queries
Methods vs member variables
if ($query->is_search
This doesn't work, and should be generating PHP warnings for you. The problem is that is_search is a function/method not a variable, it should be:
if ( $query->is_search() && $query->is_main_query() ) {
But search.php?
WordPress decides which template is loaded based on the main query. If it's the main query, and is_search is true, then search.php will be loaded.
Because of this, WordPress hasn't decided which template to use when your filter happens. In fact, you can make WordPress change which template it loads by modifying the query variables. For example, if you unset all the variables, and tell it to load a single post, you won't get search.php, or an archive at all, you're likely to get single.php instead
What About Search Queries in Page Templates?
is_main_query will be false, so not an issue
There is a workaround that might cost you an extra query. However, @Milo once mentioned that WordPress is pretty smart about caching the queries, so this shouldn't be a big deal for you.
You can run the query inside the pre_get_posts and then do some checks. If the situation matched your requirements, then filter the query:
//Filter the search for only posts and parts
function SearchFilter($query)
{
remove_action('pre_get_posts', 'SearchFilter');
// Run the query to fetch the results
$posts = get_posts( $query->query );
if(!empty($posts)) {
// Check the template for the first post
if( get_page_template_slug( $posts[0]->ID ) == 'YOUR SLUG HERE' ){
$search_template = true;
} else {
$search_template = false;
}
}
// Now filter the posts
if ($query->is_main_query() & $query->is_search && $search_template) {
$query->set('post_type', array('post', 'parts'));
$query->set('meta_key', 'Manufacturer');
$query->set('orderby', 'meta_value');
$query->set('order', 'ASC');
}
return $query;
}
add_action('pre_get_posts', 'SearchFilter');
I am trying to customize the search results for a generic search, but only if it's using the search.php template. I have other searches on my site, and I don't want this filter interfering with them. Everything works on the following code, except for is_page_template('search.php').
Once I enter that line of code as a condition, it just reverts to the normal search filtering, because my IF condition is failing. How do I only run my code if we're on the search.php page?
//Filter the search for only posts and parts
function SearchFilter($query)
{
if ($query->is_search && is_page_template('search')) {
$query->set('post_type', array('post', 'parts'));
$query->set('meta_key', 'Manufacturer');
$query->set('orderby', 'meta_value');
$query->set('order', 'ASC');
}
return $query;
}
add_filter('pre_get_posts', 'SearchFilter');
I am trying to customize the search results for a generic search, but only if it's using the search.php template. I have other searches on my site, and I don't want this filter interfering with them. Everything works on the following code, except for is_page_template('search.php').
Once I enter that line of code as a condition, it just reverts to the normal search filtering, because my IF condition is failing. How do I only run my code if we're on the search.php page?
//Filter the search for only posts and parts
function SearchFilter($query)
{
if ($query->is_search && is_page_template('search')) {
$query->set('post_type', array('post', 'parts'));
$query->set('meta_key', 'Manufacturer');
$query->set('orderby', 'meta_value');
$query->set('order', 'ASC');
}
return $query;
}
add_filter('pre_get_posts', 'SearchFilter');
Share
Improve this question
edited Jun 28, 2017 at 14:21
Johansson
15.4k11 gold badges44 silver badges80 bronze badges
asked Jun 28, 2017 at 14:15
Jordan CarterJordan Carter
2912 gold badges5 silver badges13 bronze badges
2
-
I suppose
is_page_templateruns afterpre_get_posts. That's why you can't use it yet. – Johansson Commented Jun 28, 2017 at 14:20 - 1 Yes, you're right. Is there another way to check? I'm going to experiment with WP_Query inside the template itself, but it feels kind of silly to have WordPres check the normal way, and then tell it to change its mind and try another way... – Jordan Carter Commented Jun 28, 2017 at 14:31
2 Answers
Reset to default 6Lets break it down step by step:
if ($query->is_search && is_page_template('search')) {
There are 3 problems here
is_page_template
search.php isn't a page template, that's not how the search template is loaded. So this won't work.
But if it did work, there's a new problem. Functions such as is_page_template etc rely on the main query, but we're in a pre_get_posts filter, you don't know if that query has been set yet, or if you're filtering that query or another.
So we need to:
- remove the
is_page_templatecheck, it doesn't do what you think it does - Add an
$query->is_main_query()check so the filter doesn't interfere with widgets and other queries
Methods vs member variables
if ($query->is_search
This doesn't work, and should be generating PHP warnings for you. The problem is that is_search is a function/method not a variable, it should be:
if ( $query->is_search() && $query->is_main_query() ) {
But search.php?
WordPress decides which template is loaded based on the main query. If it's the main query, and is_search is true, then search.php will be loaded.
Because of this, WordPress hasn't decided which template to use when your filter happens. In fact, you can make WordPress change which template it loads by modifying the query variables. For example, if you unset all the variables, and tell it to load a single post, you won't get search.php, or an archive at all, you're likely to get single.php instead
What About Search Queries in Page Templates?
is_main_query will be false, so not an issue
There is a workaround that might cost you an extra query. However, @Milo once mentioned that WordPress is pretty smart about caching the queries, so this shouldn't be a big deal for you.
You can run the query inside the pre_get_posts and then do some checks. If the situation matched your requirements, then filter the query:
//Filter the search for only posts and parts
function SearchFilter($query)
{
remove_action('pre_get_posts', 'SearchFilter');
// Run the query to fetch the results
$posts = get_posts( $query->query );
if(!empty($posts)) {
// Check the template for the first post
if( get_page_template_slug( $posts[0]->ID ) == 'YOUR SLUG HERE' ){
$search_template = true;
} else {
$search_template = false;
}
}
// Now filter the posts
if ($query->is_main_query() & $query->is_search && $search_template) {
$query->set('post_type', array('post', 'parts'));
$query->set('meta_key', 'Manufacturer');
$query->set('orderby', 'meta_value');
$query->set('order', 'ASC');
}
return $query;
}
add_action('pre_get_posts', 'SearchFilter');
本文标签: functionsFilter the query ONLY for the search results page
版权声明:本文标题:functions - Filter the query ONLY for the search results page 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://it.en369.cn/questions/1749212922a2333676.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。


is_page_templateruns afterpre_get_posts. That's why you can't use it yet. – Johansson Commented Jun 28, 2017 at 14:20