6

I'm struggling to make the Search module recognize the presence of a URL alias that I created for 'search/node'. It however stubbornly uses the default path.

In my template I use something like:

function mytheme_form_alter(&$form, &$form_state, $form_id) {
  switch($form_id){    
  case 'search_form':
    $form['#action'] = drupal_get_path_alias('/search/node'); // = '/' . drupal_get_path_alias('search/node') does not work either
    break;

  }
}

When the results are displayed, the URL still reads:

/search/node/[search-string]

Does anyone know whether the path is hard-coded and omits the alias function?

2 Answers 2

3

I've had a lot of misery trying to customise the URLs for the search module so I feel your pain!

It's a submit handler that redirects to the search/node page so you'll need to add your own handler to override the redirect:

function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'search_form') {
    $form['#action'] = 'search';
    $form['#submit'][] = 'MYMODULE_search_form_submit';
  }
  else if ($form_id == 'search_box_form' || $form_id == 'search_theme_form') {
    $form['#submit'][] = 'MYMODULE_search_form_submit';
  }
}

function MYMODULE_search_form_submit(&$form, &$form_state) {
  $default = search_get_default_module_info();
  $form_state['redirect'] = str_replace("$default[module]/", '', $form_state['redirect']);
}

That code comes from a module who's sole purpose is to allow users to search at search/string rather than search/node/string so you'll probably need to change a couple of things to match your alias settings, but it might help start you off.

Here's a bit of extra code that's used to override the search URL using a hook_menu_alter():

function MYMODULE_menu_alter(&$items) {
  drupal_static_reset('search_get_info');
  $default_info = search_get_default_module_info();
  if ($default_info) {
    foreach (search_get_info() as $module => $search_info) {
      $path = 'search/' . $search_info['path'];
      unset($items[$path]);
      unset($items["$path/%menu_tail"]);
    }

    $items['search/%menu_tail'] = array(
      'title' => 'Search',
      'load arguments' => array('%map', '%index'),
      'page callback' => 'search_view',
      'page arguments' => array($default_info['module'], 1),
      'access callback' => '_search_menu_access',
      'access arguments' => array($default_info['module']),
      'type' => MENU_CALLBACK,
      'file' => drupal_get_path('module', 'search') . '/search.pages.inc'
    );
  }
}

It basically removes the menu items for the search path and replaces them with a single one. It's only useful in very specific conditions (i.e. when you've only got one search type enabled) but it's something to go off at least.

4
  • Thank you for the code. Basically in my case the str_replace line should look differently, something like: $form_state['redirect'] = drupal_get_path_alias('search/node'). While it works ok in the markup (the action attributes are filled up with my alias), the address bar displays unaliased path when search has been made. Will try to google more. Apr 2, 2012 at 22:11
  • Yeah it's a real pain. I've added a bit more to the answer, maybe it'll help
    – Clive
    Apr 2, 2012 at 22:20
  • Thanks. I finally managed to get the redirect to work, but another problem appeared in which a page 'my/alias/to/search/[search-string]' could not be found. No wonder. The menu_alter hook that you've added, looked as if it were dealing with the problem, but unfortunately it does not help. On the whole, looks like it's going to consume an unjustifiable amount of time, so I guess I'm going to leave it up for someone with more Drupal programming knowledge and come to terms with unaliased URLs. Apr 2, 2012 at 22:50
  • I also had to add $items['search'] to MYMODULE_menu_alter, to prevent /search from redirecting to /search/node. Here's the code: $items['search'] = array('title' => 'Content', 'page callback' => 'search_view', 'page arguments' => array($default_info['module'], NULL), 'access callback' => '_search_menu_access', 'access arguments' => array($default_info['module']), 'type' => MENU_CALLBACK, 'file' => drupal_get_path('module', 'search') . '/search.pages.inc'); May 22, 2015 at 17:48
2

Thanks to the Clive i managed to make my own search module which adds another search path, so under mysite.com/searchpath I get search results from SEARCH_MODULE which I use.

Example "variables":
MYMODULE - your custom module which implement hooks below
SEARCH_MODULE - search module which you would like to use
searchpath - path for search results

// Custom search path alias
function MYMODULE_form_search_form_alter(&$form, &$form_state, $form_id) {
  $form['#action'] = 'searchpath';
  $form_state['action'] = 'searchpath';
  $form['#submit'][] = '_MYMODULE_search_form_submit';
}

function MYMODULE_form_search_block_form_alter(&$form, &$form_state, $form_id) {
  $form['#submit'][] = '_MYMODULE_search_form_submit';
}

function _MYMODULE_search_form_submit(&$form, &$form_state) {
  $form_state['redirect'] = 'searchpath/'.$form_state['values']['search_block_form'];
}

// Add searchpath to available paths
function MYMODULE_menu_alter(&$items) {
  $path = 'searchpath';
  $items[$path] = array(
    'title' => t('Search'),
    'page callback' => 'search_view',
    'page arguments' => array('SEARCH_MODULE', 1),
    'access callback' => '_search_menu_access',
    'access arguments' => array('SEARCH_MODULE'),
    'type' => MENU_LOCAL_TASK,
    'file' => drupal_get_path('module', 'search') . '/search.pages.inc',
    'weight' => -10, //Don't know what is it for
  );
  $items["$path/%menu_tail"] = array(
    'title' => t('Search'),
    'load arguments' => array('%map', '%index'),
    'page callback' => 'search_view',
    'page arguments' => array('SEARCH_MODULE', 1),
    'access callback' => '_search_menu_access',
    'access arguments' => array('SEARCH_MODULE'),

    // The default local task points to its parent, but this item points to
    // where it should so it should not be changed.
    'type' => MENU_LOCAL_TASK,
    'file' => drupal_get_path('module', 'search') . '/search.pages.inc',
    'weight' => 0,

    // These tabs are not subtabs.
    'tab_root' => 'searchpath/%',

    // These tabs need to display at the same level.
    'tab_parent' => 'searchpath',
  );
}

Hope that this example helps.

2
  • I cannot test it right now, but I'm voting up your answer for a good start - in return for your will to share the code. Thanks. Jun 11, 2013 at 20:48
  • In your case you should probably replace 'SEARCH_MODULE' by 'node' if you want use it as search/node alias
    – jmarceli
    Jun 12, 2013 at 18:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.