Drupal7中为Facet API添加文本框搜索过滤器的方法问询
嘿,我来帮你梳理Drupal7里给Facet API添加文本框过滤器的可行方案,还有你遇到的「先筛选内容类型再搜关键词」的问题~
先明确:Facet API本身的定位
首先得说清楚,Facet API的核心是做分面筛选(比如内容类型、分类标签这种离散值的筛选),它默认并不直接提供文本输入式的关键词过滤器——这类搜索功能其实是Drupal Search或者Search API的本职工作,但我们可以通过几种方式把文本搜索和Facet的筛选联动起来,甚至给Facet API扩展文本过滤能力。
方案1:用Search API + Views实现联动(最省心的方式)
既然你已经在用Search API,优先推荐用Views来整合两者:
- 先确认你的Search API索引里,已经把需要搜索的文本字段(比如内容标题、用户名称这类)添加并完成了索引
- 新建一个Views页面,数据源选择你的Search API索引
- 在Views的筛选条件里添加目标文本字段,选择「包含关键词」这类操作,然后把这个筛选条件设置为暴露(Exposed)——这样前端就会自动生成一个文本输入框,用户可以输入关键词搜索
- 同时,在Views的**分面(Facets)**设置里,启用你需要的分面(比如内容类型A/B/C),这样就能实现「先选内容类型,再输入关键词搜索」的联动效果,而且Views会自动处理条件叠加,不会出现筛选后搜索失效的问题
方案2:自定义模块给Facet API加文本过滤器(适合有开发能力的情况)
如果一定要用Facet API来实现文本过滤,需要写点自定义代码:
- 先创建一个自定义模块(比如叫
facet_text_filter) - 实现
hook_facetapi_widgets()来定义一个文本输入框的widget:
function facet_text_filter_facetapi_widgets() { return array( 'text_input_widget' => array( 'handler' => array( 'label' => t('Text input filter'), 'class' => 'FacetapiWidgetTextInput', 'query types' => array('term'), ), ), ); }
- 然后创建
FacetapiWidgetTextInput类,继承FacetapiWidget,重写execute()和buildQuery()方法来输出输入框并处理搜索逻辑:
class FacetapiWidgetTextInput extends FacetapiWidget { public function execute() { $element = &$this->build[$this->facet['field alias']]; // 渲染文本输入框 $element = array( '#type' => 'textfield', '#title' => $this->facet['label'], '#default_value' => isset($_GET[$this->facet['field alias']]) ? $_GET[$this->facet['field alias']] : '', '#attributes' => array('class' => array('facet-text-filter')), ); // 添加提交按钮(也可以改成AJAX提交优化体验) $element['#suffix'] = '<button type="submit" class="form-submit">' . t('Search') . '</button>'; } // 叠加文本过滤的查询条件 public function buildQuery($query) { if (!empty($_GET[$this->facet['field alias']])) { $keyword = $_GET[$this->facet['field alias']]; $query->condition($this->facet['field alias'], '%' . db_like($keyword) . '%', 'LIKE'); } return $query; } }
- 启用模块后,到Facet API的设置页面,给对应的文本字段选择这个自定义的widget,就能生成文本输入过滤器了。
解决你遇到的「筛选后搜索失效」问题
你说的先选内容类型A,再搜「Andrew」没效果的问题,本质是当前的搜索和Facet筛选没有联动:
- 如果用Views+Search API的方案,只要把内容类型的分面和文本搜索都设置为暴露的筛选条件,Views会自动叠加所有条件——也就是说选了内容类型A后,文本搜索只会在A类型的内容里查找关键词
- 如果用自定义Facet文本过滤器,只要确保
buildQuery方法里的条件和Facet的其他筛选条件(比如内容类型)是同时生效的,Search API的查询会自动合并这些条件,不会冲突
一些注意事项
- 一定要确保你的文本字段已经在Search API索引里被正确索引,否则再怎么设置都搜不到内容
- Drupal7的Search API和Facet API都是比较老旧的模块,尽量使用稳定的7.x-1.x版本,避免版本兼容问题
- 如果不需要复杂的自定义逻辑,优先用Views+Search API的组合,比写自定义模块省心太多
内容的提问来源于stack exchange,提问作者Albert Lazaro de Lara
相关产品推荐
相关产品推荐

