我有一个自定义的帖子类型叫做course
. 在课程帖子中,我有许多自定义字段,特别是(所有AFC select下拉列表):course_or_project
, time_to_complete_project
, time_to_complete_course
和difficulty
. 我还有一个分类法叫做course_project_category
.
我的目标是能够创建许多下拉列表/滑块,通过读取所述下拉列表/滑块的值并单击搜索按钮来构建URL,使用我组合的查询字符串(jQuery)来筛选正确的帖子。此功能完全正常。好有时结果有点混乱,即仅通过一些参数进行过滤。
转到代码。
我在中添加了一个函数以公开自定义字段:
function my_pre_get_posts( $query ) {
// do not modify queries in the admin
if( is_admin() ) {
return $query;
}
// only modify queries for \'course\' post type
if( isset($query->query_vars[\'post_type\']) && $query->query_vars[\'post_type\'] == \'course\' ) {
// allow the url to alter the query
if( isset($_GET[\'course_or_project\']) ) {
$query->set(\'meta_key\', \'course_or_project\');
$query->set(\'meta_value\', $_GET[\'course_or_project\']);
}
if( isset($_GET[\'time_to_complete_project\']) ) {
$query->set(\'meta_key\', \'time_to_complete_project\');
$query->set(\'meta_value\', $_GET[\'time_to_complete_project\']);
}
if( isset($_GET[\'time_to_complete_course\']) ) {
$query->set(\'meta_key\', \'time_to_complete_course\');
$query->set(\'meta_value\', $_GET[\'time_to_complete_course\']);
}
if( isset($_GET[\'difficulty\']) ) {
$query->set(\'meta_key\', \'difficulty\');
$query->set(\'meta_value\', $_GET[\'difficulty\']);
}
}
// return
return $query;
}
add_action(\'pre_get_posts\', \'my_pre_get_posts\');
查询分类法似乎是现成的。
因此,我完成的URL的一个示例可能是:
http://localhost:3000/courses/?course_project_category=jokes&course_or_project=project&difficulty=easy&time_to_complete_project=15
目前我的结果好坏参半。
从上面的查询中,我返回了2篇文章,它们大部分符合我的条件,但作为一个具体的例子,一篇文章有time_to_complete_project
值为30
即使指定了查询15
.
我想不出来。通过Chrome开发工具,我可以看到所有参数都如预期的那样:
有什么想法吗?!
Update
我有一种新的方法正在发挥作用(但缺乏验证和卫生):
// array of filters (field key => field name)
$GLOBALS[\'my_query_filters\'] = array(
\'field_1\' => \'course_or_project\',
\'field_2\' => \'difficulty\',
\'field_3\' => \'time_to_complete_project\',
\'field_4\' => \'time_to_complete_course\'
);
// action
add_action(\'pre_get_posts\', \'my_pre_get_posts\', 10, 1);
function my_pre_get_posts( $query ) {
// bail early if is in admin
if( is_admin() ) {
return;
}
if( isset($query->query_vars[\'post_type\']) && $query->query_vars[\'post_type\'] == \'course\' ) {
// get meta query
$meta_query = $query->get(\'meta_query\');
// loop over filters
foreach( $GLOBALS[\'my_query_filters\'] as $key => $name ) {
// continue if not found in url
if( empty($_GET[ $name ]) ) {
continue;
}
// get the value for this filter
// eg: http://www.website.com/events?city=melbourne,sydney
$value = explode(\',\', $_GET[ $name ]);
// append meta query
$meta_query[] = array(
\'key\' => $name,
\'value\' => $value,
\'compare\' => \'IN\',
);
}
// update meta query
$query->set(\'meta_query\', $meta_query);
}
}
SO网友:Pieter Goosen
你需要建立一个适当的meta_query
. 只有当您有一个代码时,您的代码才能工作meta_key
设置,如果你有超过1个,一切都将混乱。
另外请注意,您应该never ever 使用来自$_GET
变量(以及来自任何地方的任何值)。通过在URL中添加一些脚本,很容易将恶意代码注入站点。验证和卫生对性能的影响非常小,但绝对值得一试。
为了解决您的问题,让我们尝试重新编码您的操作。我已经在需要的地方发表了评论。
add_action( \'pre_get_posts\', function ( $q )
{
if ( !is_admin() // Do this only on the front end
&& $q->is_main_query() // Targets the main query only
) {
if( isset($query->query_vars[\'post_type\']) && $query->query_vars[\'post_type\'] == \'course\' ) { // Not sure about this, can be $q->is_post_type_archive( \'course\' )
// Get all our $_GET variables and sanitize and validate them
$course_or_project = filter_input( INPUT_GET, \'course_or_project\', FILTER_SANITIZE_STRING );
$time_to_complete_project = filter_input( INPUT_GET, \'time_to_complete_project\', FILTER_SANITIZE_STRING );
$time_to_complete_course = filter_input( INPUT_GET, \'time_to_complete_course\', FILTER_SANITIZE_STRING );
$difficulty = filter_input( INPUT_GET, \'difficulty\', FILTER_VALIDATE_INT );
// Set our variable to hold the meta_query
$meta_query = [];
// Now we build our meta_query
if( $course_or_project ) {
$meta_query[] = [
\'key\' => \'course_or_project\',
\'value\' => $course_or_project
];
}
if( $time_to_complete_project ) {
$meta_query[] = [
\'key\' => \'time_to_complete_project\',
\'value\' => $time_to_complete_project
];
}
if( $time_to_complete_course ) {
$meta_query[] = [
\'key\' => \'time_to_complete_course\',
\'value\' => $time_to_complete_course
];
}
if( $difficulty ) {
$meta_query[] = [
\'key\' => \'difficulty\',
\'value\' => $difficulty
];
}
// Make sure we have something in $meta_query before setting it
if ( $meta_query )
$q->set( \'meta_query\', $meta_query );
}
}
});
您可以根据需要优化查询,但这应该是最基本的