Take the following example:

function mymodule_example_form(&$form_state) {
  $form = array();
  $form['outer'] = array(
    '#type' => 'fieldset',
    '#title' => t('my fieldset'),
    '#collapsible' => TRUE,
    '#theme' => 'mymodule_fieldset',
  );
  $form['outer']['content'] = array(
    '#value' => '<div>hello</div>',
  );
  return $form;
}
// Theme function - so far this is a cut-and-paste of the system theme function in form.inc
function theme_mymodule_fieldset($element) {
  if ($element['#collapsible']) {
    drupal_add_js('misc/collapse.js');
    if (!isset($element['#attributes']['class'])) {
      $element['#attributes']['class'] = '';
    }
    $element['#attributes']['class'] .= ' collapsible';
    if ($element['#collapsed']) {
      $element['#attributes']['class'] .= ' collapsed';
    }
  }

  return '<fieldset'. drupal_attributes($element['#attributes']) .'>'. ($element['#title'] ? '<legend>'. $element['#title'] .'</legend>' : '') . (isset($element['#description']) && $element['#description'] ? '<div class="description">'. $element['#description'] .'</div>' : '') . (!empty($element['#children']) ? $element['#children'] : '') . $element['#value'] ."</fieldset>\n";
}

(note, I haven't even got around to customising the actual HTML output of the themed fieldset)

In this example, the contents of the fielsdet are passed to the theme function, not the fieldset itself. The output from the above will be something like:

+- my fieldset -----------------------------------------------------------+
|   +- my fieldset ----------------------------------------------------+  |
|   +-  div with hello inside  -------------------------------------+  |
|   +------------------------------------------------------------------+  |
+-------------------------------------------------------------------------+

Clearly this is wrong - the contents of the fieldset should read "hello" and just be plain text, not another fieldset!

Is this a bug, or am I doing something wrong?

(if it matters, I want to theme some fieldsets differently from others, so I can't have a system wide theme override)

Comments

dpearcefl’s picture

Is this still an issue in current D6?

tmsimont’s picture

Version: 6.0 » 6.22
Priority: Normal » Major

Definitely still an issue. I am having the same in 6.22 -- extremely odd and frustrating. Makes working with customized fieldsets impossible without hackish workarounds or theme-based alterations.

Related issue and further description on StackOverflow:
http://stackoverflow.com/questions/2762884/how-do-i-use-a-custom-theme-f...

iva2k’s picture

Version: 6.22 » 7.x-dev
Category: bug » task
Priority: Major » Normal

For Drupal 7 the answer lies in the way how form API and theme() function (which invokes the #theme hook) work together.

If theme_XXXX() is declared in hook_theme() with 'variables' key, then the element is not passed to the theme_XXXX() function (theme() function tries to populate new variables according to the 'variables' array given in theme registry).

Any theme_XXXX() that is used in '#theme' of a form element should be declared with 'render element' key (and 'variables' key should be removed altogether) in the corresponding hook_theme().

In Drupal 6 'arguments' key is used in place of 'variables' key, but logic is different in theme() function and 'render element' key is not used. I think theme() function is still affected by the way theme_XXXX() is declared in hook_theme(), but I don't have more details.

It needs to be spelled out clearly in hook_theme() documentation in respect to 'variables'/'render element' and '#theme' hooks.

rmontero’s picture

Bump.

rmontero’s picture

I was having the same issue.

The answer is #theme_wrappers:

'#type' => 'fieldset',
'#theme_wrappers' => array('mymodule_fieldset'),

Try that and tell me if it works for you

rmontero’s picture

Issue summary: View changes

Fixed rendering a little bit. Was missing the contents which are in fact displayed. Core of the issue is the double fieldset when using a custom theme designation. Theme should override, not duplicate as child