How to Theme the Comment Form in Drupal 6

June 29, 2010

Ed. Note: Learn how to theme the comment form in Drupal 7.

I’ve grown to have an affinity for Drupal’s hook_form_alter function. Truly, modifying a form doesn’t have to be as complicated as it may seem. One of the most generic Drupal forms (in my opinion) is the pesky comment form. Out of the box, it comes complete with name, email, homepage, subject, and comment fields.

Original Comment Form

Standard Comment Form

While these settings can be slighty adjusted on a content type level, the configurations available through the administrative interface are limited.

Even if you’re not a PHP guru, you should still be able to refashion the comment form to your liking through your theme’s template.php file. The first time I attempted a form_alter, I followed an excellent tutorial called Modifying Forms in Drupal 5 and 6 by Lullabot and still refer back to this article on a case-by-case basis.

Register the Theme Function

<?php
function themename_theme() {
  return array(
    'comment_form' => array(
      'arguments' => array('form' => NULL),
    ),
  );
}
?>

Before we can actually change the components of the comment form, we have to ensure Drupal’s theme layer knows to look for our new function. The code snippet above tells Drupal to look for a function called themename_theme and what arguments are available to it.

Include this code in your theme’s template.php file and double check that you’ve updated the function’s themename so that it matches your own. You'll also want to be sure you've cleared your site's cache at Administer > Performance.

Create the Override Function

<?php
function themename_comment_form($form) {
$output = '';
//print "<pre>";
//return print_r($form);
//print "</pre>";
$output .= drupal_render($form);
return $output;
}
?>

The code above represents the "wrapper" where all our overrides will occur. Add this to your template.php file, and temporarily uncomment the three lines of preformatted output. Now, when you visit your form, you should see a long list of data. These variables will assist you in writing your overrides.

Adding Fieldsets to Drupal's Comment Form

//Create new fieldsets
$form['information'] = array(
   '#type' => 'fieldset',
   '#title' => t('Your Information'),
   '#collapsible' => FALSE,
   '#weight' => 1,
);
$form['your_comment'] = array(
   '#type' => 'fieldset',
   '#title' => t('Your Comment'),
   '#collapible' => FALSE,
   '#weight' => 2,
);

In order to organize existing fields into manageable sections, we'll have to define fieldsets in our new function. To create the two new fieldsets, "Your Information" and "Your Comment," I included the code snippet above (immediately following the preformatted code inside the "wrapper" function).

Next we'll need to assign fields to our new fieldsets and unset their current structure. We can do this using the following method:

//Unset & Move Name field into "Your Information" fieldset
$form['information']['name'] = $form['name'];
unset($form['name']);

When it comes time for you to define these on your own, remember, print_r($form) is your friend!

Removing the Homepage Field

//Remove the Homepage field
$form['homepage'] = NULL;

Anytime you want something to be entirely removed from a form, this method above is much stronger than using a CSS display:none hack. You can apply this same principle to any of the form elements. In our case, I also applied this technique to the email's description.

I'd also suggest using the Better Formats module to remove the Input Field that appears for anonymous users. It's safer to grant this permission only to site administrators or authenticated users due to the risk of spammers entering malicious code.

Modified Comment Form

Modified Comment Form

You can see that I've added two fieldsets to the form, removed the homepage field altogether, changed the label for email, removed its description, and changed the "Save" button's value. All of these changes happened in the theme's template.php file.

This new form will be much nicer to theme and no longer screams that it's a cookie-cutter Drupal form. Once the Garland look is changed up a bit, there's a lot to go off of here.

The following code is the complete code for the finalized form above.

/**
* Implementation of hook_theme.
*
* Register custom theme functions.
*/

function themename_theme() {

  return array(
    'comment_form' => array(
      'arguments' => array('form' => NULL),
    ),
  );
}

/**
 * Customizations to the Comment form.
 *
 */

function themename_comment_form($form) {

  $output = '';
  //print "<pre>";
  //return print_r($form);
  //print "</pre>";  

  //Create new fieldsets
  $form['information'] = array(
    '#type' => 'fieldset',
    '#title' => t('Your Information'),
    '#collapsible' => FALSE,
    '#weight' => 1,
  );

  $form['your_comment'] =array(
    '#type' => 'fieldset',
    '#title' => t('Your Comment'),
    '#collapsible' => FALSE,
    '#weight' => 2,
  );

  //Your Name
  $form['information']['name'] = $form['name'];
  unset($form['name']);
  $form['information']['name']['#required'] = 1;

  //Email Address
  $form['information']['mail'] = $form['mail'];
  unset($form['mail']);
  $form['information']['mail']['#title'] = t('Email Address');

  $form['information']['mail']['#description'] = NULL;

  $form['information']['mail']['#required'] = 1;

  //Homepage
  $form['homepage'] = NULL;

  //Subject
  $form['your_comment']['subject'] = $form['subject'];
  unset($form['subject']);
  $form['your_comment']['subject']['#weight'] = -10;

  //Comment
  $form['your_comment']['comment_filter']['comment'] = $form['comment_filter']['comment'];
  unset($form['comment_filter']['comment']);

  //Submit
  $form['submit']['#value'] = t('Submit Comment');

  $output .= drupal_render($form);

  return $output;
}

And there you have it! Hope you find this useful.

Comments

Nice tutorial! I'll try it

Nice tutorial! I'll try it tonight. Thank you!

Help

Hi,

I'm a Drupal Noob and I must be being stupid because I've done the first bit of the tutorial.

function thestreetsavvy_theme() {
return array(
'comment_form' => array(
'arguments' => array('form' => NULL),
),
);
}

/**
* Customizations to the Comment form.
*
*/
function thestreetsavvy_comment_form($form)
{
$output = '';
print "

";
return print_r($form);
print "

";
$output .= drupal_render($form);
return $output;
}

and I'm getting the following error:

warning: Missing argument 2 for comment_form(), called in /var/www/html/sites/ukscenic.com/themes/thestreetsavvy/page.tpl.php on line 147 and defined in /var/www/html/modules/comment/comment.module on line 1246.

It's looking for a value for $edit.

Any ideas,

Thanks,

Sean

Sean, your code looks good.

Sean, your code looks good. I hate to ask such an obvious question, but have you tried clearing your Drupal cache? (admin → settings → performance) Also, what theme is thestreetsavvy based on (and what version)? I'd also take a look at line 147 in your page template file. Is that where the $edit variable comes into play?

Suppressing the e-mail field

The real problem with it is that suppressing it is very easy. But the core still checks its validity and there doesn't seem to be a way to omit this check without modifiying the core--with all the implications that carries...

Doesn't work for me

Zen theme = no go. Fatal errors, or no change at all.

Any way to change the comment

Any way to change the comment form based on node type? Example: I want a "Review" form for product type and a "Comment" form for a blog.

Sam, Sure it can be done.

Sam,

Sure it can be done. You just need to wrap your form code in a conditional statement like this:


if ($node->type = 'product' ) {

[Review form code]

}
else {

[Comment form code]

}

Hope that helps.

warning: Missing argument 2

warning: Missing argument 2 for comment_form(), called in /var/www/html/sites/ukscenic.com/themes/thestreetsavvy/page.tpl.php on line 147 and defined in /var/www/html/modules/comment/comment.module on line 1246.

Sean, That isn't a lot to go

Sean,

That isn't a lot to go on.

Can you post the code on line 147 of page.tpl.php?

Thanks.
Art

Any idea how you might

Any idea how you might implement this in Drupal 7?

Dan, hook_form_alter hasn't

Dan,

hook_form_alter hasn't changed from D6 to D7 so it should be very similar. Is there a specific error or issue you are running into?

We will likely revisit this article soon to update it to D7 so check back in a few weeks.

Art

Well i've added your code to

Well i've added your code to my template.php and registered the comment form array with my existing hook_theme implementation, however when trying to view a node that has the comment form no error appears, the page just continuously tries to load... I checked Drupals logs and there are many many

Undefined index: comment_filter, etc

errors, all I presume relating to elements of the form.

Any idea how I would go about fixing this?

Cheers

The problems is with the

The problems is with the comment form structure. It's changed from D6 to D7.

The comment body in D6 was stored in $form['comment_filter'] but in D7 it's $form['comment_body']

If you change this:

//Comment
$form['your_comment']['comment_filter']['comment'] = $form['comment_filter']
['comment'];
unset($form['comment_filter']['comment']);

to this:

//Comment
$form['your_comment']['comment_body']['comment'] = $form['comment_body']
['comment'];
unset($form['comment_body']['comment']);

that might get rid of your errors, but I haven't tested it.

There may be other parts of the comment form that have changed so I would recommend looking at the Drupal API

Plus you can install the Devel module and chart out the new form structures for D7.

Hope that helps.

Dan, Here is the post I

Dan,

Here is the post I promised on Theming the comment form in Drupal 7

Art

Thank you so much, this has

Thank you so much, this has helped me greatly! All the best

Nice Article

Nice Article

Thanks, Sowmi!

Thanks, Sowmi!

It doesn't work. Because

It doesn't work. Because &variables is not a paramater of our function.Can you please help me about this. I need to display different [comment-filter][#title] for each node type. I tried your suggestion but it didn't work. node->type is not described I think

Thanks! This is the first

Thanks! This is the first page that spelled this out in a way I could understand. Appreciate it!

Glad you found it helpful,

Glad you found it helpful, Amanda.