我已经创建了一个自定义帖子类型,并附加了一些自定义字段。现在,我希望作者可以在自定义帖子列表屏幕(在管理后端)上执行的搜索也可以在元字段上执行,而不仅仅像往常一样查看标题和内容。
我可以挂接到哪里,我必须使用什么代码?
Example image
斯特凡诺
我已经创建了一个自定义帖子类型,并附加了一些自定义字段。现在,我希望作者可以在自定义帖子列表屏幕(在管理后端)上执行的搜索也可以在元字段上执行,而不仅仅像往常一样查看标题和内容。
我可以挂接到哪里,我必须使用什么代码?
Example image
斯特凡诺
我通过在Posteta表中添加连接并更改where子句来解决过滤查询的问题。筛选WHERE子句(通常需要正则表达式搜索和替换)的提示如下here on codex:
add_filter( \'posts_join\', \'segnalazioni_search_join\' );
function segnalazioni_search_join ( $join ) {
global $pagenow, $wpdb;
// I want the filter only when performing a search on edit page of Custom Post Type named "segnalazioni".
if ( is_admin() && \'edit.php\' === $pagenow && \'segnalazioni\' === $_GET[\'post_type\'] && ! empty( $_GET[\'s\'] ) ) {
$join .= \'LEFT JOIN \' . $wpdb->postmeta . \' ON \' . $wpdb->posts . \'.ID = \' . $wpdb->postmeta . \'.post_id \';
}
return $join;
}
add_filter( \'posts_where\', \'segnalazioni_search_where\' );
function segnalazioni_search_where( $where ) {
global $pagenow, $wpdb;
// I want the filter only when performing a search on edit page of Custom Post Type named "segnalazioni".
if ( is_admin() && \'edit.php\' === $pagenow && \'segnalazioni\' === $_GET[\'post_type\'] && ! empty( $_GET[\'s\'] ) ) {
$where = preg_replace(
"/\\(\\s*" . $wpdb->posts . ".post_title\\s+LIKE\\s*(\\\'[^\\\']+\\\')\\s*\\)/",
"(" . $wpdb->posts . ".post_title LIKE $1) OR (" . $wpdb->postmeta . ".meta_value LIKE $1)", $where );
$where.= " GROUP BY {$wpdb->posts}.id"; // Solves duplicated results
}
return $where;
}
Stefano的回答很好,但缺少一个明确的条款:
function segnalazioni_search_distinct( $where ){
global $pagenow, $wpdb;
if ( is_admin() && $pagenow==\'edit.php\' && $_GET[\'post_type\']==\'segnalazioni\' && $_GET[\'s\'] != \'\') {
return "DISTINCT";
}
return $where;
}
add_filter( \'posts_distinct\', \'segnalazioni_search_distinct\' );
添加上面的代码更新它,它将不会重复工作。This will work,
function custom_search_query( $query ) {
$custom_fields = array(
// put all the meta fields you want to search for here
"rg_first_name",
"rg_1job_designation"
);
$searchterm = $query->query_vars[\'s\'];
// we have to remove the "s" parameter from the query, because it will prevent the posts from being found
$query->query_vars[\'s\'] = "";
if ($searchterm != "") {
$meta_query = array(\'relation\' => \'OR\');
foreach($custom_fields as $cf) {
array_push($meta_query, array(
\'key\' => $cf,
\'value\' => $searchterm,
\'compare\' => \'LIKE\'
));
}
$query->set("meta_query", $meta_query);
};
}
add_filter( "pre_get_posts", "custom_search_query");
Answer 1:在函数文件中添加此代码,并更改和添加更多在自定义帖子类型中使用的列名称
function extend_admin_search( $query ) {
// use your post type
$post_type = \'document\';
// Use your Custom fields/column name to search for
$custom_fields = array(
"_file_name",
);
if( ! is_admin() )
return;
if ( $query->query[\'post_type\'] != $post_type )
return;
$search_term = $query->query_vars[\'s\'];
// Set to empty, otherwise it won\'t find anything
$query->query_vars[\'s\'] = \'\';
if ( $search_term != \'\' ) {
$meta_query = array( \'relation\' => \'OR\' );
foreach( $custom_fields as $custom_field ) {
array_push( $meta_query, array(
\'key\' => $custom_field,
\'value\' => $search_term,
\'compare\' => \'LIKE\'
));
}
$query->set( \'meta_query\', $meta_query );
};
}
add_action( \'pre_get_posts\', \'extend_admin_search\' );
Answer 2: Recommended在函数文件中使用此代码,无需任何更改function cf_search_join( $join ) {
global $wpdb;
if ( is_search() ) {
$join .=\' LEFT JOIN \'.$wpdb->postmeta. \' ON \'. $wpdb->posts . \'.ID = \' . $wpdb->postmeta . \'.post_id \';
}
return $join;
}
add_filter(\'posts_join\', \'cf_search_join\' );
function cf_search_where( $where ) {
global $pagenow, $wpdb;
if ( is_search() ) {
$where = preg_replace(
"/\\(\\s*".$wpdb->posts.".post_title\\s+LIKE\\s*(\\\'[^\\\']+\\\')\\s*\\)/",
"(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where );
}
return $where;
}
add_filter( \'posts_where\', \'cf_search_where\' );
function cf_search_distinct( $where ) {
global $wpdb;
if ( is_search() ) {
return "DISTINCT";
}
return $where;
}
add_filter( \'posts_distinct\', \'cf_search_distinct\' );
使用此代码,您可以search 在WordPress管理面板的帖子列表中custom post meta 值以及title 和其他默认字段。
请在函数中添加以下代码。php文件:
if (!function_exists(\'extend_admin_search\')) {
add_action(\'admin_init\', \'extend_admin_search\');
/**
* hook the posts search if we\'re on the admin page for our type
*/
function extend_admin_search() {
global $typenow;
if ($typenow === \'your_custom_post_type\') {
add_filter(\'posts_search\', \'posts_search_custom_post_type\', 10, 2);
}
}
/**
* add query condition for custom meta
* @param string $search the search string so far
* @param WP_Query $query
* @return string
*/
function posts_search_custom_post_type($search, $query) {
global $wpdb;
if ($query->is_main_query() && !empty($query->query[\'s\'])) {
$sql = "
or exists (
select * from {$wpdb->postmeta} where post_id={$wpdb->posts}.ID
and meta_key in (\'custom_field1\',\'custom_field2\')
and meta_value like %s
)
";
$like = \'%\' . $wpdb->esc_like($query->query[\'s\']) . \'%\';
$search = preg_replace("#\\({$wpdb->posts}.post_title LIKE [^)]+\\)\\K#",
$wpdb->prepare($sql, $like), $search);
}
return $search;
}
}
它不是一个搜索,而是通过不同的值进行“选择”。
在文件中functions-iworks-posts-filter.zip 您有一个如何通过一些meta\\u键为常规帖子添加过滤器的示例。我认为它很容易转换。
在pre\\u get\\u posts中修改搜索WP\\u查询的meta\\u查询参数的两个答案中的代码版本不再搜索post\\u标题。如果不修改SQL,就无法在WP\\U查询中直接添加搜索帖子标题或元数据的功能,很遗憾,正如此问题所阐述的:Using meta query ('meta_query') with a search query ('s')
我在这里结合了一些技术,得到了一个可以避免preg\\u替换和太多SQL修改的工作版本(我希望可以完全避免)。唯一的缺点是,在搜索之后,页面顶部的字幕文本会显示“搜索结果”。我刚刚用CSS为插件的自定义帖子类型隐藏了它。
/**
* Extend custom post type search to also search meta fields
* @param WP_Query $query
*/
function extend_cpt_admin_search( $query ) {
// Make sure we\'re in the admin area and that this is our custom post type
if ( !is_admin() || $query->query[\'post_type\'] != \'your_custom_post_type\' ){
return;
}
// Put all the meta fields you want to search for here
$custom_fields = array(
"your_custom_meta_field",
"your_custom_meta_field2",
"your_custom_meta_field3"
);
// The string submitted via the search form
$searchterm = $query->query_vars[\'s\'];
// Set to empty, otherwise no results will be returned.
// The one downside is that the displayed search text is empty at the top of the page.
$query->query_vars[\'s\'] = \'\';
if ($searchterm != ""){
// Add additional meta_query parameter to the WP_Query object.
// Reference: https://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters
$meta_query = array();
foreach($custom_fields as $cf) {
array_push($meta_query, array(
\'key\' => $cf,
\'value\' => $searchterm,
\'compare\' => \'LIKE\'
));
}
// Use an \'OR\' comparison for each additional custom meta field.
if (count($meta_query) > 1){
$meta_query[\'relation\'] = \'OR\';
}
// Set the meta_query parameter
$query->set(\'meta_query\', $meta_query);
// To allow the search to also return "OR" results on the post_title
$query->set(\'_meta_or_title\', $searchterm);
}
}
add_action(\'pre_get_posts\', \'extend_cpt_admin_search\');
/**
* WP_Query parameter _meta_or_title to allow searching post_title when also
* checking searching custom meta values
* https://wordpress.stackexchange.com/questions/78649/using-meta-query-meta-query-with-a-search-query-s
* https://wordpress.stackexchange.com/a/178492
* This looks a little scary, but basically it\'s modifying the WHERE clause in the
* SQL to say "[like the post_title] OR [the existing WHERE clause]"
* @param WP_Query $q
*/
function meta_or_title_search( $q ){
if( $title = $q->get( \'_meta_or_title\' ) ){
add_filter( \'get_meta_sql\', function( $sql ) use ( $title ){
global $wpdb;
// Only run once:
static $nr = 0;
if( 0 != $nr++ ) return $sql;
// Modified WHERE
$sql[\'where\'] = sprintf(
" AND ( (%s) OR (%s) ) ",
$wpdb->prepare( "{$wpdb->posts}.post_title LIKE \'%%%s%%\'", $title),
mb_substr( $sql[\'where\'], 5, mb_strlen( $sql[\'where\'] ) )
);
return $sql;
});
}
}
add_action(\'pre_get_posts\', \'meta_or_title_search\');
如何使permalink可用于搜索结果页/?s=一+二+确定到/搜索/一-二确定/感谢