I wanted to theme my facet links, but found that the function drupal_html_id() generates a different 'unique' ID for every facet on page refresh. Not practical for theming purposes, since you don't want that facet to change appearance when you click on them. My solution was to just copy the basic link widget to a separate module, take this function out, and replace it with a css-safe version of the link text from the $attributes array. This will generate the same ID every time, and theming can be safely done.

The attached module will give you an extra widget choice in the facet settings: 'themeable links'. It's a quick and dirty solution, but maybe it's useful or inspiring to someone.

Similar to this issue: http://drupal.org/node/1367612

Members fund testing for the Drupal project. Drupal Association Learn more


Alan D.’s picture

Version: 7.x-1.3 » 7.x-1.x-dev
Assigned: BParticle » Unassigned
Category: task » feature
Priority: Minor » Normal
Status: Active » Needs review
9.67 KB
2.1 KB
PASSED: [[SimpleTest]]: [MySQL] 566 pass(es). View

The following patch add's a wrapper theming function to the widget_links item list and would let users do whatever they like with the links.

i.e. This allowed us to turn the link list into a jumper menu with minimal effort.

This is kind of a duplicate of #1367612: Use renderable arrays for facetapi links but without the complete duplication of theme_item_list(), aka it doesn't add functionality, just provides the hook to integrate with the block.


Simple globally loaded JScript used.

(function ($, Drupal, window, document, undefined) {
  Drupal.behaviors.facetapiJumperMenu = {
    attach: function(context, settings) {
      $('.facetapi-jumper-menu select', context).once('facetapi-jumper-menu', function() {
        $(this).change(function () {
          window.location = $(this).val();
})(jQuery, Drupal, this, this.document);

And the theme code to activate the jumper:

function THEME_facetapi_widget_links($variables) {
  $element = $variables['element'];
  $build = $element['#build'];
  $widget = $element['#widget'];
  $widget_build = $widget->getBuild();
  $output = '';
  if ($options = _theme_facetapi_link_options($build, t('Choose one...'))) {
    $output = '<div class="facetapi-jumper-menu">';
    $select = element_info('select');
    $title = empty($widget_build['#title']) ? t('Filter by') : t('Filter by !title', array('!title' => $widget_build['#title']));
    $select['#title'] = $title;
    $select['#options'] = $options;
    $output .= render($select);
    $output .= '</div>';
  return $output;

function _theme_facetapi_link_options($items, $empty_option = NULL, $depth = 0) {
  global $base_url;
  $options = array();
  if ($depth == 0 && $empty_option) {
    $options[''] = $empty_option;
  foreach ($items as $item) {
    if (empty($item['#active'])) {
      $label = $item['#markup'] . ($item['#count'] ? ' (' . $item['#count'] . ')' : '');
    else {
      $label = '(-) ' . $item['#markup'];
    $href = url($item['#path'], array('query' => empty($item['#query']) ? array() : $item['#query'], 'absolute' => TRUE));
    $options[$href] = ($depth ? str_repeat('-', $depth) . ' ' : '') . $label;
    if (!empty($item['#item_children'])) {
      // Render nested list.
      $options += _theme_facetapi_link_options($item['#item_children'], NULL, $depth + 1);
  return $options;
cpliakas’s picture

Looks like a pretty slick technique. I would definitely be in favor of committing this. Anyone else using this patch? Can we confirm that it won't break existing implementations? Would love to get an RTBC from a tester.

Thanks for the contribution,

Alan D.’s picture

I guess people would need to run update.php to clear the theme registry. I used devel to flush the caches.

mike.davis’s picture

I've used this patch to theme the links in the way that I wanted to and this works great for that.

Robert Castelo’s picture

Issue summary: View changes

+1 from me, works great and is very useful.

I've used this to display date range facets as drop down selects, and also to add field labels for improved accessibility.

cpliakas’s picture

Status: Needs review » Needs work

Marking as needs work because it fails to apply to HEAD.

Overall functionality looks great, and I have enough +1's to make me feel good about committing the change

Thanks for the contribution,

narkoff’s picture

I am using #1 to display Date Range facets in a drop down. However, I have one basic question. I have two drop downs and want the title option value of the drop down to be different for each drop down. My PHP knowledge is limited, when I change the following line in template.php, it changes the title for both drop downs:

if ($options = _theme_facetapi_link_options($build, t('Choose one...'))) {

How can I have a unique title for each drop down? Thanks!

Alan D.’s picture

We no longer are supporting the site that this was done for. But install Devel on your localhost, and dpm($element); This should show you things that can be used to identify the element.

Make sure you remove the dpm() before deploying the code :)

narkoff’s picture

@Alan D. Thank you for the Devel guidance. I did a dpm( get_defined_vars() ); This showed me the path to the facet Title. I then changed the referenced line in #7 above from 'Choose one...' to the path $widget_build['#title']. Now each of my drop downs shows their own facet title.

steinmb’s picture

Status: Needs work » Needs review
2.11 KB

Re-roll of patch. Looks RTBC to me. theme_facetapi_widget_links() is called.

steinmb’s picture