Help with #theme on the form element level

himerus - June 21, 2009 - 04:45
Project:Drupal
Version:6.12
Component:forms system
Category:bug report
Priority:normal
Assigned:Unassigned
Status:active
Description

I recently posted here regarding help with hook_theme, and #theme on form level items. However, this seems to be more of an issue than anything. It seems to fall between poor documentation and maybe my lack of understanding on theming at the module level.

I've had several needs lately to override theme functions on the module level that were definitely outside the theme layer, and needed to be controlled by the functionality of a module.

The Rundown

I'm trying to create a custom theme_checkboxes function for my module. However, it simply MUST NOT be allowed to interact with every call to theme_checkboxes. I had one solution on a past project where this was acceptable, but now it is not.

Please be gentle if I'm taking the entirely wrong approach, and point me in the right way.
I'm only posting the relevant portions of code to keep it as short as possible.

The Code

hook_theme

<?php
function taxonomy_rockstar_theme() {
  return array(
   
'tr_layout_checkboxes' => array(
      
'arguments' => array('element'),
    ),
  );
}
?>

theme_tr_layout_checkboxes

<?php
function theme_tr_layout_checkboxes($element) {
 
$class = 'tr-layout-checkboxes';
  if (isset(
$element['#attributes']['class'])) {
   
$class .= ' '. $element['#attributes']['class'];
  }
 
$element['#children'] = '<div class="'. $class .'">'. (!empty($element['#children']) ? $element['#children'] : '') .'</div>';
  if (
$element['#title'] || $element['#description']) {
    unset(
$element['#id']);
    return
theme('form_element', $element, $element['#children']);
  }
  else {
    return
$element['#children'];
  }
}
?>

PLEASE NOTE: the current code in this theme_checkboxes function is EXACTLY the same as the default theme_checkboxes.

Now I'm trying to use #theme on the type=checkboxes array in my form. according to the api it says #theme is available on the element level, NOT JUST the top level of $form, although, the only examples I can find are declaring a theme function for an entire form.

The Form

<?php
$form
['tr']['tr-used-layouts'] = array(
   
'#type' => 'checkboxes',
   
'#theme' => 'tr_layout_checkboxes',
   
'#title' => t('Available Layouts'),
   
'#description' => t('You may choose to enable/disable layouts that are by default enabled by sub modules, and exclude them from the specific vocabulary setting pages. This will prevent admins from selecting one of those layout options for a vocabulary, AND will not allow it to be chosen by users who have the ability to modify the filter/interface. <em>If NO options are selected here, it will be assumed you do NOT want to filter these layout types</em>'),
   
'#required' => FALSE,
   
'#default_value' => variable_get('tr-used-layouts', array()),
   
'#options' => taxonomy_rockstar_generate_layouts(),
  );
?>

The Real Problem

Okay, with that code posted, here is the real issue I'm having. I CAN get my theme function to be called in 2 situations.

  1. by using '#theme' => 'tr_layout_checkboxes' as it is currently declared in the code.
  2. by renaming tr_layout_checkboxes to simply checkboxes in hook_theme, and removing the #theme declaration on the form level
    • HOWEVER, this makes it be used for EVERY call to checkboxes

In the second case above, the form works just fine, and my checkboxes are rendered, as well as the rest of the form.

In the first case, however, the function is also being called, but when I enter the function using the code as posted above in hook_theme, the $elements['children'] is not set, and not rendering the child checkboxes. (remember, my custom theme function is currently using the EXACT same code as the default theme_checkboxes function) All that ends up being rendered at the moment is the label and description, TWICE... I'm truly baffled where this is coming from, and can't track down the location.

I'm kind of lost here, and banging my head against the wall on this one. I've looked at panels and other various modules for examples, and just can't seem to find what I need.

Thanks in advance for taking the time to read this over, and point me in the right way.

#1

himerus - June 21, 2009 - 14:13
Category:support request» bug report

After some more testing, I think this has to be some sort of a bug. I've seen no posts anywhere on how to use the #theme on the form element level, and in my last test, I REMOVED the custom reference in hook_theme so that it would default back to the main function from form.inc.

Everything is rendered as expected, and #children is a part of the array when calling theme_checboxes.

When swtiching back to my custom theme_checkboxes, WITH THE EXACT SAME CODE INTERNALLY it breaks, #children is not available.

 
 

Drupal is a registered trademark of Dries Buytaert.