I'm playing with theming forms, and put the following in my theme's template.php file:

function mythemename_node_form($form) {		
  $output = form_render($form);
  return $output;
}

As I understand it, this should do nothing at all... my output form xhtml should be identical with or without the above code.

However, without this template.php function, my page structure goes like this:

... > form#node-form > div > div.node-form > div.standard > div.form-item > ...

*With* the template.php function, my page structure goes like this:

... > form#node-form > div > div.form-item > ...

In the latter, I don't get the div.node-form and div.standard DIVs.

Can anyone explain why?

Comments

pwolanin’s picture

you are, in fact, overrriding a core theme function in the node module:

function theme_node_form($form) {
  $output = "\n<div class=\"node-form\">\n";
  if (isset($form['node_preview'])) {
    $output .= form_render($form['node_preview']);
  }

  // Admin form fields and submit buttons must be rendered first, because
  // they need to go to the bottom of the form, and so should not be part of
  // the catch-all call to form_render().
  $admin = '';
  if (isset($form['author'])) {
    $admin .= "    <div class=\"authored\">\n";
    $admin .= form_render($form['author']);
    $admin .= "    </div>\n";
  }
  if (isset($form['options'])) {
    $admin .= "    <div class=\"options\">\n";
    $admin .= form_render($form['options']);
    $admin .= "    </div>\n";
  }
  $buttons = form_render($form['preview']);
  $buttons .= form_render($form['submit']);
  $buttons .= isset($form['delete']) ? form_render($form['delete']) : '';

  // Everything else gets rendered here, and is displayed before the admin form
  // field and the submit buttons.
  $output .= "  <div class=\"standard\">\n";
  $output .= form_render($form);
  $output .= "  </div>\n";

  if (!empty($admin)) {
    $output .= "  <div class=\"admin\">\n";
    $output .= $admin;
    $output .= "  </div>\n";
  }
  $output .= $buttons;
  $output .= "</div>\n";

  return $output;
}

---
Work: BioRAFT

jeff h’s picture

Yikes... so I am! I normally override theme functions very deliberately, after having hunted them down. I came to this from an entirely different angle.

I guess my questions now then are:

* how come my overriding function changed *so little* in the output xhtml? ie why is the output code virtually identical except for two DIVs, when I have replaced about 30 lines of code with 2?

* what is "best practice" in theme function overrides? If I need to do something with the node/add page, and thus want to theme with this function, should I copy the entire theme_node_form function into my template.php and change it as appropriate? If so, what happens if some tiny part of this function is updated in a future Drupal security release? I would have to locate the change and make it manually in my overriding theme function, yes? Seems a bit involved?

Would it instead be possible (and sensible) to do something like this:

function mythemename_node_form($form) {
	
  //change $form as required by my theme eg
  //$form['taxonomy']['#collapsed'] = TRUE;
		
  $output = theme_node_form($form);
  return $output;
}

ie call the original theme_node_form function after having made my changes to the $form array?

Thanks,
Jeff

pwolanin’s picture

I would think the above will work, but why not implement hook_form_alter in a small module rather than trying to do it at the theme level?

---
Work: BioRAFT

jeff h’s picture

Will check out hook_form_alter...

Thanks for your help, it's much appreciated :)