How to implement custom theme functions like theme_textfield or theme_form_element?

I know we can do it using hook_theme_registry_alter:

 * Implements hook_theme_registry_alter().
function krown_admin_theme_registry_alter(&$theme_registry) {

  //Override some Drupal defaul theme functions

  $theme_registry['textfield']['theme path'] = drupal_get_path('module', 'krown_admin');
  $theme_registry['textfield']['function'] = 'krown_admin_theme_textfield';
  $theme_registry['textarea']['theme path'] = drupal_get_path('module', 'krown_admin');
  $theme_registry['textarea']['function'] = 'krown_admin_theme_textarea';
  $theme_registry['form_element']['theme path'] = drupal_get_path('module', 'krown_admin');
  $theme_registry['form_element']['function'] = 'krown_admin_theme_form_element';
  $theme_registry['form_element_label']['theme path'] = drupal_get_path('module', 'krown_admin');
  $theme_registry['form_element_label']['function'] = 'krown_admin_theme_form_element_label';


The problem with this approach, is that the custom functions are applied on all website. I just want to apply them for some forms or for a specific theme.


Those theme functions don't get a reference to the form where the element is used. Therefore, they cannot be used to alter an element for a single form.

Every form element accepts #theme, so you can alter the #theme function used for those form fields in a single form. This is what Drupal does in node_filter_form().

  $form['filters'] = array(
    '#type' => 'fieldset',
    '#title' => t('Show only items where'),
    '#theme' => 'exposed_filters__node',

theme_exposed_filters() then does its job.

  $form = $variables['form'];
  $output = '';

  if (isset($form['current'])) {
    $items = array();
    foreach (element_children($form['current']) as $key) {
      $items[] = drupal_render($form['current'][$key]);
    $output .= theme('item_list', array('items' => $items, 'attributes' => array('class' => array('clearfix', 'current-filters'))));

  $output .= drupal_render_children($form);

  return '<div class="exposed-filters">' . $output . '</div>';

Unfortunately, this doesn't work with theme_form_element() or theme_form_element_label().

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.