Drupal 6: Creating a custom Lucene Search facet from taxonomy and integrating into the search form block
In this tutorial I’ll show how you to create a custom Lucene Search facet from taxonomy and integrate into the search form block. A great first step would be to review the Drupal Lucene API documentation (see luceneapi.api.php PHP file in the luceneapi module folder).
I assigned the search form block to a region in my theme (admin/build/block), which generates this form:
I added a new vocabulary called “Topics”, and added a few terms (admin/content/taxonomy).
The goal of this code is to integrate the Topic vocabulary into the search form block to allow the user to select a taxonomy term as they search. To start, you need to implement a hook_luceneapi_facet_realm() and a callback function in your custom module.
<?php
/**
* Implements hook_luceneapi_facet_realm()
*/
function MYMODULE_luceneapi_facet_realm() {
$realms = array();
$realms['form'] = array(
'title' => t('Search form block'),
'callback' => 'MYMODULE_luceneapi_facet_realm_callback_search_form_block',
'callback arguments' => array(),
'allow empty' => TRUE,
'description' => t('Displays facets in the search form block.'),
);
return $realms;
}
/**
* Implements hook_luceneapi_facet_realm() callback function
*/
function MYMODULE_luceneapi_facet_realm_callback_search_form_block($facets, $realm, $module) {
$form = array();
// loop through facets
foreach ($facets as $name => $facet) {
// NOTE: luceneapi_facet_to_fapi_convert() converts a Lucene facet to Drupal Form API data
$form = array_merge_recursive($form, luceneapi_facet_to_fapi_convert($facet));
}
return $form;
}
?>
At this point if you go to the facets admin page (admin/settings/luceneapi_node/facets), you can see the newly created realm. I assigned the taxonomy vocabulary “Topic” to this realm.
Up next is implementing a hook_form_alter() to integrate the facet into the search form.
<?php
/**
* Implementation of hook_form_FORM_ID_alter().
*/
function MYMODULE_form_search_block_form_alter(&$form, &$form_state) {
// get default search module (IE: luceneapi_node)
$module = luceneapi_setting_get('default_search');
// check if default search module is defined in lucene searchable module list
if (array_key_exists($module, luceneapi_searchable_module_list())) {
// get index type (IE: node)
$type = luceneapi_index_type_get($module);
// fetch realm facets
$elements = luceneapi_facet_realm_render('form', $module, $type);
// if facet form elements exist, recursively merge with current form object
if (!empty($elements)) {
$form = array_merge_recursive($form, $elements);
}
}
}
?>
The search from block should now show an empty “Topic” facet.
The last piece of code implements hook_luceneapi_facet_postrender_alter() which gives you the opportunity to modify the facet, and in the this case, add its options.
Immediately after implementing this hook, if you krumo() or dsm() the $items argument, you’ll see the form element has no options.
The next section of code copied the contrib module code in “Lucene Node”. [See file: luceneapi/contrib/luceneapi_node/luceneapi_node.module; function: function luceneapi_node_luceneapi_facet_postrender_alter()]
<?php
/**
* Implements hook_luceneapi_facet_postrender_alter()
*/
function MYMODULE_luceneapi_facet_postrender_alter(&$items, $realm, $module, $type = NULL) {
if ($realm == 'form' && $module == 'luceneapi_node' && $type == 'node' && is_array($items['category'])) {
// get taxonomy form data
$taxonomy = module_invoke('taxonomy', 'form_all', 1);
// get enabled facets
$facets_enabled = luceneapi_facet_enabled_facets_get($module, $realm);
// loop through enabled facets, validate, and fetch weight
$weights = array();
foreach ($facets_enabled as $name => $value) {
// check for "category" facet
// FORMAT: category_{VOCABID}
if (preg_match('/^category_(\d+)$/', $name, $match)) {
// load taxonomy vocabulary
if ($vocabulary = taxonomy_vocabulary_load($match[1])) {
// ensure category and vocab id is enabled for this module and realm
if (luceneapi_facet_enabled($match[0], $module, 'form')) {
// fetch weight
$variable = sprintf('luceneapi_facet:%s:%s:%s:weight', $module, $realm, $name);
$weights[$vocabulary->name] = variable_get($variable, 0);
}
}
}
// end foreach
}
// gets weighted taxonomy array
asort($weights);
$taxonomy_weighted = array();
foreach ($weights as $vocab_name => $weight) {
$taxonomy_weighted[$vocab_name] = $taxonomy[$vocab_name];
}
// create array of fapi data to override
$category_data = array(
'#prefix' => '<div class="criterion">',
'#suffix' => '</div>',
//'#size' => 10,
'#options' => $taxonomy_weighted,
'#multiple' => TRUE,
'#default_value' => luceneapi_facet_value_get('category', array()),
'#title' => NULL,
'#description' => NULL,
);
// merge data
$items['category'] = array_merge($items['category'], $category_data);
// sets weight as the lowest weight of all taxonomy facets
if (is_array($items['category']['#weight'])) {
$items['category']['#weight'] = min($items['category']['#weight']);
}
// end if
}
}
?>
Reloading the page will now show the search form with a completed facet.
Submitting the search form block with a selected taxonomy term will now take the user to the search results page with the taxonomy facet pre-selected!