drupal development. drupal support. drupal training.

How to customise the comment form in Drupal 6

Published on Sat, 2009-11-14 12:44

Most forms in drupal can be customised, or 'themed' by writing a few lines of code in your theme's template.php file. However, the comment form is one of a few exceptions where this doesn't work - not with a little extra magic anyway.

As always, there is more than one possible approach, some of them are good, some bad. In this article, we'll be doing it the right way - The Drupal way.

A little inside information...

if you were to look inside comment.module which can be found in your Drupal installation at /modules/comments/comment.module you would probably notice the comment_form() function which is responsible for actually building the comment form using the Forms API. However, unlike other modules that build forms in a similar way, what the comment module doesn't do is register a corresponding theme_ function for the form, which you need in order to be able to control it's output using a theme_ function.

Tip: To get a better understanding of how forms are built and themed, have a read of the Forms API Quickstart Guide, particularity relevant to this discussion is section 2 under the heading 'Theming forms'.

Registering a theme function

So, to be able to theme the comment form, we need to register our own theme function for this form. If your theme is a subtheme of the excellent zen theme, you can do this in your template,php file like so:

/**
 * Implementation of hook_theme().
 */
function mytheme_theme(&$existing, $type, $theme, $path) {
  $hooks = zen_theme($existing, $type, $theme, $path);
  // Add your theme hooks like this:
  /*
  $hooks['hook_name_here'] = array( // Details go here );
  */

  $hooks['comment_form'] = array(
    'arguments' => array('form' => NULL),
    // Note: by uncommenting the following line, you can also use a
    // template file named comment-form.tpl.php to control the
    // output of the form. 
    /*'template' => 'comment-form', */
  );

  return $hooks;
}

Note: you must rename the theme function so it matches the name of your theme (replace mytheme with the name of your theme).

If your theme is not a subtheme of zen, your function will be a little simpler and should look more like this:

/**
* Implementation of hook_theme().
*/
function mytheme_theme(){
  return array(
    'comment_form' => array(
      'arguments' => array('form' => NULL),
    ),
  );
}

 

The theme function itself

You can theme create the theme_comment_form function, again in your theme's template.php file. In my case, I wanted to rename the 'Your name' field to just 'Name', the 'Homepage' field to 'Website' and 'Comment' to 'Your message'. I also wanted to add a little help message to the homepage field, as I don't think it is clear to everybody what the field is for. I also removed the preview button as I don't feel it's needed.

/**
* Theme the output of the comment_form.
*
* @param $form
*   The form that  is to be themed.
*/
function mytheme_comment_form($form) {

  // Rename some of the form element labels.
  $form['name']['#title'] = t('Name');
  $form['homepage']['#title'] = t('Website');
  $form['comment_filter']['comment']['#title']  = t('Your message');

  // Add some help text to the homepage field.
  $form['homepage']['#description'] = t('If you have your own website, enter its address here and we will link to it for you. (please include http://).');
  $form['homepage']['#description'] .= '<br/>'. t('eg. http://www.kirkdesigns.co.uk');

  // Remove the preview button
   $form['preview'] = NULL;

  return drupal_render($form);
}

Altering the 'Post new comment' heading

On top of that, I also wanted to change the title of the comments form which by default says 'Post new comment'. This is actually generated elsewhere - in the function theme_box. Because this is already created by a theme_ function, there is no need for us to register our own theme_ function so we can go straight in and use use Drupal 6's preprocess function (still in your theme's template.php) file to modify the template variables before they are passed into the theme_box function:

function mytheme_preprocess_box(&$vars, $hook) {
  switch($vars['title']) {
   case 'Post new comment':
    $vars['title'] = t('Leave a comment or suggestion...');
  }
}

On a similar note, you might be interested in my article on Customizing the search box in Drupal 6.

Comments

Submitted by Anonymous (not verified) on

Hi,

Thank you for this article. Can you tell me if it's possible to add a new field from CCK? I need to add a dropdown list.

Thank you in advance.

Regards, Julien

Submitted by tom on

Hi Julien,

In Drupal 6, comments are not nodes, and so you can not add CCK fields to them. In Drupal 7, comments are 'fieldable' so you will be able to extend them in this way.

However, for Drupal 6 you may want to check out the Node Comments module, which you can use instead of the core comments module, and allows you to designate a content type that can be used for comments. This should allow you to use all the goodness of CCK fields in your comment form.

Submitted by Anonymous (not verified) on

Hello,

Can you tell me if it's possible to customise the override function in order to use it only for a particular node or content type?

Thank you.

Submitted by tom on

Once way you could do this is by using an if statement in your theme function to check the node type, and only make modifications if it is a certain type. However, this information isn't readily available in the theme function, so you need to look it up first. Adjust your theme_comment_form function as follows:

{syntaxhighlighter brush: php;fontsize: 100; first-line: 1; }function mytheme_comment_form($form) { // Look up the node type. $nid = $form['nid']['#value']; $node = node_load(array('nid' => $nid)); // Only edit the comment form if the node type is 'story'. if ($node->type == 'story') { // Your form customisations here } return drupal_render($form); } {/syntaxhighlighter}

Obviously, you can change 'story' to the name of the content type you are interested in modifying.

Submitted by Nathaniel (not verified) on

Hi, thanks for the great article. I followed along step by step, but it doesn't seem to be having any impact at all on the way my contact form is beind displayed. I'm working with a sub theme of Zen (my subtheme is called ICH).

I tried to do something similar to this yesterday -- to add custom regions to my site for blocks. Modifying the template.php file didn't work for that, either, but modifying the zen.info (or, in my case, the ich.info) file did work. Does that mean I'm missing a setting to allow these kind of overrides to work? Or could it be something else?

Any help is greatly appreciated. I'm new to Drupal, and getting my head wrapped around all the different ways to modify output has been slow-going.

Submitted by tom on

Hi Nathaniel

Did you clear your theme registry after making the changes (specifically, after adding the region to your theme's .info file)?

If you have the devel module installed, you can do this at:

Admin -> Flush all caches -> Theme registry

Submitted by Nathaniel (not verified) on

Hi Tom, Right before you posted this, I read about clearing the cache in Drupal. Did that, and the edits in your example came through. Thanks very much, for your time, and for sharing your expertise. Its been a big help!

Submitted by Nathaniel (not verified) on

So I was able to change "homepage" to website, etc... But do you happen to know how I would remove the hints and the line "More information about formatting options" from beneath the large comment box? I'm using TINYMce (although I've disabled it for the comments form by modifying its JavaScript).

Is it similar to how you modified the first batch of elements? Or would that particular element be something different altogether?

Submitted by tom on

Hi Nathaniel,

You should take a look at the Better Formats module. Amongst other things, this module introduces a new permission which allows you to hide the more the format tips link.

Submitted by Anonymous (not verified) on

Great stuff. This has been a lot of help to me. The one outstanding issue I've had is the Button on the comment form. By default it says "Save" and I want to change that to "Submit Comment". Here's what I've tried: $form['submit']['#value'] = t('Submit comment');and this does indeed change the button's text but then the comment form doesn't work at all. Comments are not submitted and the form and the comments vanish. Any idea what I'm doing wrong? 

Submitted by ajayg (not verified) on

Thanks fora great writeup. I am able to create a new template comment-form.tpl.php based on your writup. Thank you.

Now I am stumped.  How can I know which variables are available for me in this template?   There are some hidden variables as well like "form_build_id" which need correct value for form to validated.  Where can I get this list?

Submitted by tom on

To inspect the available variables in the comment-form.tpl.php file, you should install the devel module, and then use the dsm() function. In template.php, create a new preprocess function for this purpose. Something like this:

{syntaxhighlighter brush: php;fontsize: 100; first-line: 1; }mytheme_preprocess_comment_form($vars) { dsm($vars); }{/syntaxhighlighter}

That should show you the full content of $vars. Each key in the $vars array is available as a variable in the template file. So, for example if there is a $vars['somekey'], then $somekey is available for use in the template file. Note that you will need to clear your theme registry after adding the preprocess function to template.php.

Submitted by ajayg (not verified) on

thanks. I figured it out.   But still baffled how to add a region in that areas since that varable won't be available to comment_form. So wondering if you know the solution.

Submitted by wils (not verified) on

Hi Tom,Thank you for the excellent article!I have  a question: How could I have the comment form above the comments list?thank you 

Submitted by Anonymous (not verified) on

Hi, Thanks for the lovely write-up. Very useful!

I'm trying to display the avatar of the currently logged-in user next to the comment form. (kinda like what Facebook used to have, and it was very inviting to quickly post comments).  If the user is anonymous, or does not have an avatar, then the default avatar should be displayed.

I searched and searched for such snippet, but no result. Quite a few people would love such feature, but there is no write-up for people who are not coding gurus.  

Could you possibly help? Thank you in advance!

Submitted by chandrabhan (not verified) on

Well, somehow managed to implement that. This is how my _comment_form funtion look like in template.php                     function <themename>_comment_form($form) {  global $user;  $pic = theme('user_picture', $user);  $form['name']['#title'] = t('Name');   $form['homepage']['#title'] = t('Website');  $form['comment_filter']['comment']['#title'] = t('Your message');   // Add some help text to the homepage field.  $form['homepage']['#description'] = t('If you have your own website, enter its address here and we will link to it for you. (please include http://).');  $form['homepage']['#description'] .= '<br/>'. t('eg. http://www.google.com');   // Remove the preview button  $form['preview'] = NULL;   $output = ''.$pic;  $output .= drupal_render($form['name']);  $output .= drupal_render($form);   return $output;}Dont forget to theme the picture appropriately. You might have to play around with the margin and floats and all.

Hi,       You can configure your comment avataars by setting your Theme Configuration. "/admin/build/themes/configure". its a feature available in global settings of your currently active theme. You also have to set Comment Picture  from User settings.    

Submitted by Daniele (not verified) on

You dont have to use hooks for that: go in admin/build/themes/settings/your_theme_here and check the 'User pictures in comments' checkbox. 

Submitted by Anonymous (not verified) on

I found tons of examples for altering the comment form, but none of them were done through zen theme's organization of the template.php. Bless your soul for posting this.

Is there a way to have drupal comments print out something like this:"John replied to Jack" I'm using flat displayed comments (which is an organised mess) and this would improve readability. I've been bugged by this for ever :/

Submitted by Anonymous (not verified) on

in your comment form there are five form elements how you increases the comment form elements in the core drupal comment module only two fields subject and comment

Submitted by Glenn (not verified) on

Great tutorial, thanks. Everything works beautifully, including the function preprocess_box technique to change the title of the comments form. Just struggling with one thing: how to change the comments form title for one content type only?Thanks.

Submitted by Lavada (not verified) on

Hi - Thanks so much for posting this article, I have been racking my brain trying to figure out how to change this form, I am glad to read that this will all be integrated in to drupal 7.I would like to just remove the Homepage label and textbox field from the form is this possible?

Great tut on faffing around with the comment form, very handy. Just a quick question though, I can't seem to find any help anywhere for this but how would you give some feedback to the user when they add a comment, something lke an alert saying "thanks for your comment, blah blah". Any help would be fantastic!Cheers

Submitted by Strae (not verified) on

You should use some hook to act when the comment is submitted (dont know exactly wich hook, checkl the drupal api) and then use the drupal_set_message function. 

Off the top of my head one thing you could potentially do is set up a custom Rule using the rules module so that a message was generated or an email was sent every time a user posts a comment?

Submitted by Sepero (not verified) on

Took me about 5 hours to figure out that this wouldn't work because I already had a function defined for  MyThemeName_theme()You might want to make a note of that for other retards like me.

Submitted by Anonymous (not verified) on

Seems that the suggested ideas by tom in this article do not apply to Acquia Marina theme (based on fusion_core). Changing the template.php of fusion_core causes php errors.

 I wasnt able to test the zen code, but i couldn't get your other sample code for non-zen themes to work. I endded up implementing this in a custom module with a hook_form_alter.Since your comment form doenst work for pasting code, check out my sample code on pastebin:http://pastebin.com/DJ47XUMyAs you can see its virtually the same code except that you don't need to define hook_theme() and you don't need to render the form.

Submitted by Luis (not verified) on

If for some reason you want to enable comments on a particular node type, but hide the comments and the form, I found a way to do it, is not probably the best but it will work.You'll have to alter the node/% link using hook_menu_alter to use your own callback for displaying nodes. Drupal uses 'node_page_view', you just go and copy that function.On that function, you'll change node_show($node, $cid) for yourown_node_show($node, $cid). Now copy the node_show function and alter it to suit your needs.

Submitted by scott (not verified) on

Thanks for this, very useful.  How would I go about modifying your code if I wanted to remove the homepage field altogether from my form? I don't want users to be able enter a url there.  Nor do I want them to be able to enter any HTML code into the comment content.thanks again!scott

Submitted by nikosnikos (not verified) on

In a multilingual site you'll have to use t('Post new comment') in the case statement of mytheme_preprocess_box :function mytheme_preprocess_box(&$vars, $hook) {  switch($vars['title']) { case t('Post new comment'):    $vars['title'] = t('Leave a comment or suggestion...');  } }

Add new comment