I need to theme a node content type as a form. For example, the node has fields:

field_body = a question, e.g. "What is your favourite color?"
field_answers = field collection ------------------> these will become radio buttons
    field_content = an answer, e.g. "Blue"
    field_internal = internal value for the radio button
    field_points = how many points for this answer ---------> this will become an html attribute
    field_additional = "some additional info about this answer ---------> this will become an html attribute

and so on, each question has 3 answers to choose. This is a questionnaire, the editor adds questionnaires dynamically. I don't want Webform module in this case.

So far I've written a mymodule_theme() function (in a custom module) for the whole node with answers, and themed it as a form using raw html output, something like this:

$output = '<form>';
... loop
$output .= '<input type="radio" name="myquestion" value="' . $field_internal_value . '"> . $field_content_value .'<br>'

But Drupal has form API. I could as well build a $form render array in mymodule_theme(), instead of raw html and then use:

$output = drupal_render($form)

The question:

in the above example, is there any real advantage of building a form array and rendering it using drupal_render, instead of building the output from raw html as shown? For example, advantage with using ajax later, or submitting, or validating "the Drupal way" etc. (I think not because form API applies only to static forms which are defined in a module, but I'm not sure).

  • I might have missed something, but is the node themed as a form not just the node/edit form itself? There are many ways to customise the display of node edit.. – autopoietic Dec 17 '13 at 0:27

Using the Form API instead of doing things in the theme layer (rendering the node as a form) will give you all the advantages that the Form API has to offer (e.g. custom validation, submit handlers, form alters, etc.)

I would do things differently by creating a menu item with drupal_get_form as the page callback and the node as the parameter.

 * Implements hook_menu().
function example_menu() {
  $items = array();

  $items['custom/%node'] = array(
    'title callback' => 'node_page_title',
    'title arguments' => array(1),
    'page callback' => 'drupal_get_form',
    'page arguments' => array('example_custom_form', 1),

  return $items;

 * Form constructor that takes a node as a parameter and creates a form based
 * on its values.
function example_custom_form($form, &$form_state, $node) {
  $form['#node'] = $node;

  // Start generating the form...

  return $form;

Although subjective, this feels a little less hacky and might be easier to maintain in the future.

  • I am using a theme because such questionnaire nodes are not intended to be viewed "normally" on node/* path (because such view would not make sense). According to the form API, after building the questionnaire form I realized that the API applies to my form the same way it applies to e.g. node/edit form. It doesn't matter that the form is based on dynamic (node) data. Knowing this, of course, building the form instead of using raw html is a good idea. – camcam Dec 17 '13 at 11:14

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.