在Wordpress中启用自定义字段搜索
在Wordpress中撰写帖子时,您可以设置某些自定义字段。Wordpress的默认搜索行为是仅搜索帖子的标题和主要文本,这使得这些自定义字段并非全部有用。稍加修改,您就可以让Wordpress搜索您设置的任何自定义字段,因此,如果存储“作者”之类的内容,则可以允许人们通过单击链接或进行搜索来查看该作者的所有帖子。要查看有关Wordpress自定义字段的更多信息,请参阅此WordpressCodex网站文章。Wordpress将这些自定义字段存储在称为postmeta的表中,其中每个自定义字段名称(称为meta_key)都与一个自定义字段值(称为meta_value)相关联。
WordPress仅通过接受某些已知参数(例如用于搜索的s和用于查看页面的p)来工作。为了使Wordpress接受新的搜索参数,然后将其包含在搜索中,您必须编辑核心Wordpress文件。你需要的两个主要文件classes.php,并query.php在wp-includes文件夹。没有其他文件可编辑,因此您只需要查看这些文件即可。您对核心Wordpress文件进行的调整越多,在新版本问世时更新系统就越困难,因此我将这种编辑保持在最低水平。
首先,在classes.php中找到以下行,它应该在顶部附近。
var$public_query_vars=array('m','p','posts','w','cat','withcomments','withoutcomments','s','search','exact','sentence','debug','calendar','page','paged','more','tb','pb','author','order','orderby','year','monthnum','day','hour','minute','second','name','category_name','tag','feed','author_name','static','pagename','page_id','error','comments_popup','attachment','attachment_id','subpost','subpost_id','preview','robots');
这是Wordpress将接受为GET或POST请求的已知变量的列表。在此示例中,我将调用变量meta_key,使其适合表中值的名称。因此,要传递变量meta_key,您需要将其添加到此参数列表中。
var$public_query_vars=array('m','p','posts','w','cat','withcomments','withoutcomments','s','search','exact','sentence','debug','calendar','page','paged','more','tb','pb','author','order','orderby','year','monthnum','day','hour','minute','second','name','category_name','tag','feed','author_name','static','pagename','page_id','error','comments_popup','attachment','attachment_id','subpost','subpost_id','preview','robots','meta_key');
就是classes.php了,您现在可以将其关闭并打开query.php。我们仍然需要让Wordpress接受我们的自定义变量作为搜索的一部分,因此fill_query_vars()在第380行找到名为的函数。此函数以数组的定义开头,以相同的方式将变量名添加到该数组的末尾就像我们在classes.php文件中所做的一样。
function fill_query_vars($array){ $keys = array( 'error' , 'm' , 'p' //为简洁起见,删除了代码... , 'preview' , 'meta_key' );
接下来,您将不得不更改搜索功能以允许您构造新的搜索字符串。在第900行附近找到以以下代码开头的行。
//如果指定了搜索模式,请加载匹配的帖子 if ( !empty($q['s']) ) {
注释掉此if语句,并在其下面粘贴以下代码。
//如果指定了搜索模式,请加载匹配的帖子 if ( !empty($q['s']) ) { //尽早添加带有引号分组的斜杠螺钉,所以稍后再做 $q['s'] = stripslashes($q['s']); if ($q['sentence']) { $q['search_terms'] = array($q['s']); } else { preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $q[s], $matches); $q['search_terms'] = array_map(create_function('$a', 'return trim($a, "\\"\'\\n\\r ");'), $matches[0]); } $n = ($q['exact']) ? '' : '%'; $searchand = ''; if($q['meta_key']){ $q['meta_key'] = stripslashes($q['meta_key']); $join = " INNER JOIN ".$wpdb->postmeta." ON ".$wpdb->posts.".ID = ".$wpdb->postmeta.".post_id " ; $distinct = 'DISTINCT'; foreach((array)$q['search_terms'] as $term) { $term = addslashes_gpc($term); $search .= "{$searchand}((post_title LIKE '{$n}{$term}{$n}') OR (post_content LIKE '{$n}{$term}{$n}') OR (meta_value LIKE '{$n}{$term}{$n}'))"; $searchand = ' AND '; } $term = addslashes_gpc($q['s']); if (!$q['sentence'] && count($q['search_terms']) > 1 && $q['search_terms'][0] != $q['s'] ){ $search .= " OR (post_title LIKE '{$n}{$term}{$n}') OR (post_content LIKE '{$n}{$term}{$n}') OR (meta_value LIKE '{$n}{$term}{$n}')"; } $search .= " AND meta_key = '".$q['meta_key']."'"; }else{ foreach((array)$q['search_terms'] as $term) { $term = addslashes_gpc($term); $search .= "{$searchand}((post_title LIKE '{$n}{$term}{$n}') OR (post_content LIKE '{$n}{$term}{$n}'))"; $searchand = ' AND '; } $term = addslashes_gpc($q['s']); if (!$q['sentence'] && count($q['search_terms']) > 1 && $q['search_terms'][0] != $q['s'] ) $search .= " OR (post_title LIKE '{$n}{$term}{$n}') OR (post_content LIKE '{$n}{$term}{$n}')"; } if ( !empty($search) ) $search = " AND ({$search}) "; }
这会在帖子标题,内容和自定义字段上进行全文搜索,这可能会导致一些奇怪的结果。要使Wordpress仅搜索帖子标题和自定义字段,您可以像这样去掉SQl字符串的post_content部分。
foreach((array)$q['search_terms'] as $term) { $term = addslashes_gpc($term); $search .= "{$searchand}((post_title LIKE '{$n}{$term}{$n}') OR (meta_value LIKE '{$n}{$term}{$n}'))"; $searchand = ' AND '; } $term = addslashes_gpc($q['s']); if (!$q['sentence'] && count($q['search_terms']) > 1 && $q['search_terms'][0] != $q['s'] ){ $search .= " OR (post_title LIKE '{$n}{$term}{$n}') OR (meta_value LIKE '{$n}{$term}{$n}')"; }
您现在可以关闭query.php文件,因为我们从这里不再需要它。为了使您能够实际使用我们刚刚完成的工作,您需要更改模板文件。如果您的模板没有functions.php文件,请创建一个。该文件包含将与模板一起使用的功能。将以下代码添加到此文件。
function get_meta_search_query() { return apply_filters( 'get_meta_search_query', stripslashes( get_query_var( 'meta_key' ) ) ); } function the_meta_search_query() { echo attribute_escape( apply_filters( 'the_meta_search_query', get_meta_search_query() ) ); } function generateSelect($name,$options,$default=''){ $html = ''; return $html; }
接下来,编辑包含您的搜索表单的文件。在Wordpress2.3的默认模板中,该模板包含在一个名为searchForm.php的文件中。它具有以下占用空间。