I have exposed filter of taxonomy with dropdown. I want to override the dropdown menu, so that when I filter through this exposed filter, the url contains title of taxonomy and not the ID of taxonomy.

So, I have used hook_form_alter to override this dropdown, and made it in the form,

<option value='TEXT'>TEXT</option>,

initially it was like

<option value='ID'>TEXT</option>,

But in this case it is not filtering out any results, please suggest how can I make it work.

Thanks for your time.

4 Answers 4


If I'm understanding correctly, you're trying to pass an argument from an exposed filter to a contextual filter, on a Views page? If so, it seems like you haven't built the contextual filter part.

  1. Add a Contextual Filter, "Has taxonomy term ID"
  2. Enable "Specify validation criteria"
  3. Set validator to "Taxonomy" and pick your vocabulary.
  4. Under "Filter value type", choose "Term name converted to Term ID." Click Apply.
  5. Make sure the Views page path is set to something with an argument -- i.e., "/your-search-page/%" -- the % tells Views to expect some kind of argument.

Let me know how this works. Note in the future, it helps if you post the code you've tried (Even a View export).

  • I tried this, but in this case, how exposed filter will be handled, in anyways exposed filter will adds it's query string to URL, exposed filter will not be replaced by particular URL argument component. Jan 21, 2013 at 11:20

Implementing hook_form_alter() alone is not enough. The View query will check the taxonomy by term id. Now you just altered it to title in the dropdown values.

You would then need to implement hook_views_query_alter() and alter the query condition as your need. Assuming you have a taxonomy term field field_cat, your view query will have the following similar condition - field_data_field_cat.field_cat_tid = {the_selected_value}

enter image description here
Now, you need to check it against taxonomy_term_data.name:

function MYMODULE_views_query_alter(&$view, &$query){
    if($view->name == 'your_view_name'){
        $conditions = $query->where[1]['conditions'];
        $k = 0;
        foreach($conditions as $cnd){
            if($cnd['field'] == 'field_data_field_cat.field_cat_tid'){
                $replaced_condition = array(
                    'field' => 'taxonomy_term_data_field_data_field_cat.name',
                    'value' => $cnd['value'],
                    'operator' => $cnd['operator']
                $query->where[1]['conditions'][$k] = $replaced_condition;

Hope this helps.


It depends on the purpose.

If you want the the url to look something like http://example.com/viewurl?name=taxonomyname Then you should do the following

1) Create a taxonomy view instead of a content view. This is done by selecting taxonomy from the drop down of "Show"
2) Add a filter Taxonomy term: Name make it exposed
3) Add the required fields. Please note that if you want to add the fields in the content then you need to create a relationship of the type Taxonomy term: Content with term other wise you would not be able to display the content fields.
4)This would create the exposed field as a text field and not a drop down. So now in your custom field you would need to convert the text field to a drop down using a custom module where you would use the [hook_form_alter][1] to change the element to a drop down. You will need to get the entire terms to create the options. For this you would be using the function [taxonomy_term_load][2]

That was the answer for what you asked.

Now if your purpose is just to create clean url for your results then you should use the contextual filters instead of the filter criteria.


Normally you can change that in hook_form_alter():

 * Implements hook_form_alter().
function foo_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'views_exposed_form' && $form_state['view']->name != 'YOUR_VIEW_NAME') {

      foreach ($form['select_list']['#options'] as $key => &$value) {
        // your code here
        if ($value === '') {
          $value = t('Example default value');
      } // end: foreach

  } // end: if

You can also override the value in the preprocess function of the specific element, e.g. my function to override the select value, but you'd need to change the list of #options list, as you could have illegal choice error:

 * Implements hook_preprocess_[themeFunctionName]().
function foo_preprocess_select(&$variables) {
  switch (arg(0)) {
    case 'panel_url':
      if (@$variables['element']['#name'] == 'DROPDOWN_NAME') { // name of your select list
        $options = isset($variables['element']['#options']) ? array_change_key_case(array_flip($variables['element']['#options']), CASE_LOWER) : array();
        $selected = end((arg()));
        if (array_key_exists($selected, $options)) {
          if ($variables['element']['#value'] <> $options[$selected]) {
            $variables['element']['#value'] = $options[$selected];
          } else {
            // drupal_goto('panel_url');

Your Answer

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

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