1

Problem

I'm trying to register a new theme function based off theme_item_list to alter the display of a facet.

Theme_item_list is passed in an array $variables. Crucially I can't work out how the facetAPI passes the variables needed for theme_item_list to render a list. It sets up the array in the execute method of FacetapiWidgetLinks and somehow successfully passes this to theme_item_list but I can't get my own theme function to receive anything.

How does theme_item_list receive it's $variables array?

More Information

Code altered thanks to kiamlaluno

I currently have the following code in my module:

function my_module_theme($variables) {
  return array(
    'item_list_aggregate' => array('variables' => array(
      'items' => array(),
      'attributes' => array(),
      'title' => NULL,
      'type' => 'ul', 
  )));
}

//this is correctly called but $variables is empty
function theme_item_list_aggregate($variables) {
  $items = $variables['items'];
  $title = $variables['title'];
  $type = $variables['type'];
  $attributes = $variables['attributes'];
  ...

#items and #attributes values are set in the execute method below.

They are correctly passed to theme_item_list because I can't get them to pass to my theme function, theme_item_list_aggregate, the $variables variable in my_module_theme is empty.

class FacetapiWidgetLinks extends FacetapiWidget {

...

public function execute() {
    $element = &$this->build[$this->facet['field alias']];
    $this->setThemeHooks($element);

    // Here I call my own theme function. It's identical
    // to theme_item_list at the moment but my own theme function
    // never gets passed the $element array.
    if(strpos($this->facet['field alias'],"aggregation") != FALSE) {
      $element = array(
        '#theme' => 'item_list_aggregate',
        '#items' => $this->buildListItems($element),
        '#attributes' => $this->build['#attributes'],
      );
    } else {
      $element = array(
        '#theme' => 'item_list',
        '#items' => $this->buildListItems($element),
        '#attributes' => $this->build['#attributes'],
      );
    }
  }

...
1
+50

It is not necessary to create a new theme function. You could use the existing theme_item_list and extend it with double underscore. Rename item_list_aggregate to item_list__aggregate in FacetapiWidgetLinks::execute. And implement theme_item_list and theme_item_list__aggregate in your theme.

Look at node_title_list in core, this function uses the same pattern.

  • Brilliant, thanks very much! I'm not entirely sure why it works, but it does definitely work. – Dominic Woodman Mar 14 '15 at 13:29
  • The fallback logic is in theme (Comment, If there's no implementation, check for more generic fallbacks ...) – webflo Mar 17 '15 at 0:17
0

The hook_theme() implementation is wrong: The first argument passed to the hook is not the list of the variables to pass to the theme function. Your hook should be implemented with code similar to the following one.

function my_module_theme($variables) {
  return array(
    'item_list_aggregate' => array('variables' => array(
      'items' => 'default value for the variable',
      'title' => 'default value for the variable',
      'type' => 'default value for the variable', 
      'attibutes' => 'default value for the variable',
  )));
}

For a list of parameters passed to hook_theme() see hook_theme(). Keep in mind that most hook_theme() implementation don't use them.

  • Ah so that is a problem, but maybe I explained my original problem badly. The problem is I can't work out how to get the default value for items and attributes to pass to the theme function. They're set in the execute method above and theme_item_list receives them in $variables but my implementation theme_item_list_aggregate doesn't. – Dominic Woodman Mar 7 '15 at 16:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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