WordPress theming, the comment_form() call, and the power of Less

When preparing the upload of the next version of JBST to wordpress.org I found the usage of comment_form(). The documentation of comment_form() can be found at Function Reference/comment form. The documentation of comment_form() doesn’t explain why you should have to use this comment_form() call instead of code your comment form’s HTML directly into your comments.php template. On the first sight using comment_form() and setting the comment form field’s HTML by PHP as an function argument or inside a filter, seems the break the MVC principle. Templates should not contain PHP code at all.
Arguments to motivate the usage of comment_form() can be found at WordPress 3.0 Theme Tip: The Comment Form. Standardization is an important argument:

The comment_form function is new to 3.0. Basically, it standardizes the comments form. It makes it wonderful for us plugin authors, since now we can easily modify the comments form with various hooks and things.

When using comment_form() the HTML of the form fields can be set in two different ways, as shown below:

In the first place you can use the comment_form_default_fields filter. The comment_form_default_fields filter return an associative array which contains the HTML for each field as can be seen in the following code:


add_filter( 'comment_form_default_fields', function(){ 

	$commenter = wp_get_current_commenter();
	$req = get_option( 'require_name_email' );

	return array(

    'author' =>
      '<div class="form-group">
			  <label for="author">' . __("Name",'jamedo-bootstrap-start-theme')
			 . ($req ? " (". __("required",'jamedo-bootstrap-start-theme') .")" : '')
			 . ' </label>
			  <div class="input-group">
			  	<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
			  	<input class="form-control" type="text" name="author" id="author" value="'
			  	. esc_attr($commenter['comment_author']). '" placeholder="'
			  	. __("Your Name",'jamedo-bootstrap-start-theme'). '"'
			  	. ($req ? ' required aria-required="true"' : ''). '/>'
			  . '</div>'
		  	. '</div>',

    'email' =>
      '<div class="form-group">
			  <label for="email">' . __("Email",'jamedo-bootstrap-start-theme')
			 . ($req ? " (". __("required",'jamedo-bootstrap-start-theme') .")" : '')
			 . ' </label>
			  <div class="input-group">
			  	<span class="input-group-addon"><i class="glyphicon glyphicon-envelope"></i></span>
			  	<input class="form-control" type="email" name="email" id="email" value="'
			  	. esc_attr($commenter['comment_author_email']). '" placeholder="'
			  	. __("Your Email",'jamedo-bootstrap-start-theme'). '"'
			  	. ($req ? ' required aria-required="true"' : ''). '/>'
			  . '</div>'
			  . '<span class="help-block">'. __("will not be published",'jamedo-bootstrap-start-theme'). '</span>'
		  	. '</div>',

    'url' => '<div class="form-group">
			  <label for="author">' . __("Website",'jamedo-bootstrap-start-theme')
			 . ' </label>
			  <div class="input-group">
			  	<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
			  	<input class="form-control" type="url" name="url" id="url" value="'
			  	. esc_attr($commenter['comment_author_url']). '" placeholder="'
			  	. __("Your Website",'jamedo-bootstrap-start-theme'). '"'
			  	. '/>'
			  . '</div>'
		  	. '</div>'
    );}
  );

Secondly, the comment form field’s HTML can set with the array which is passed as an argument to comment_form() as follows:


$args = array ('fields'=> array('author' => '<input id="author" type="text" name="author" />'));
comment_form($args);

Please notice that the value of fields overwrites the settings of the comment_form_default_fields filter. The preceding code don’t set an email or url field which means the comment form won’t have these field too.

When using comment_form() in your templates you don’t have to code the different situations where the user is logged in or not, where the comments are open or closed, and so on. On the other hand you still have to code the function’s argument or filters as shown in the preceding.

Popular themes such as “Twentythirteen” use the comment_form() code which enables (plugin) developers to change the look and feel of the comment form with filters or CSS. In this standard situation theme coders only have to write comment_form() in the comments.php template and style the form with CSS.

WooCommerce

The WooCommerce Plugin uses the comment_form() code to build a review form. The code to create the review form will like that shown as in the following code:


comment_form( apply_filters( 'woocommerce_product_review_comment_form_args', $comment_form ) );

 

The additional woocommerce_product_review_comment_form_args filter adds extra flexibility for theme and plugin developers. In the following figure you will see how WooCommerce default review form will look:

WooCommerce's review form

JBST’s comments form

For JBST the comments form should be build with Bootstrap’s form classes and structures as can be found at: . To change the default input fields I use comment_form_default_fields filter as shown earlier in this text. Other changes are set by the argument passed to the comment_form() function as shown in the following code:


	comment_form(

			apply_filters ('jbst_comments_form_arguments', array('comment_notes_before' => '',
			'comment_field' => $comment_field,
			'title_reply' => $title_reply))
	);

 

The comment_form() function has no filters to change the submit button. You can change the text and the ID of the submit button with the argument array, but are not enable to change the HTML of the button (input type="submit"). The submit button can be styled with CSS. To style the submit button in JBST Bootstrap’s button classes are used. This button classes can be applied easily with Less. JBST has a built-in Less compiler. To style the submit button with Bootstrap’s button classes I use the Less code as follows:


#commentform {
	input[type="submit"] {
	&:extend(.btn all, .btn-primary all);
	}
}	

 

The .btn-primary button style class is variable in JBST, so the final Less code in PHP will look like the following:


#commentform {
	input[type="submit"] {
	&:extend(.btn all, .'.get_theme_mod( 'default_button_style', 'btn-primary' ).' all);
	}
}	

 

The following figure will show you how JBST comments form will look after the changes described in the preceding:

JBST's comment form

 

One Response to “WordPress theming, the comment_form() call, and the power of Less”

  1. RIck H

    Good tutorial. Used it to develop my own customized contact form plugin, where I re-define the $args for the comment form fields.

    But it turns out, while testing, that some themes create their own ‘textarea’ field, which adds to my ‘textarea’ field, resulting in two comment text fields. Not good.

    I have set my add_filter( ‘comment_form_default_fields’, my_function(), 99,1) with a higher priority (99) so that it happens later in the ‘page build’ (after the theme does it’s comment_form_default_fields), but the duplicates comment text boxes are still there. Also tried a priority of 8, and that didn’t do it either.

    I also tried unset($arg) (the parameter passed to my_function; contains the array of fields/etc), and a unset($_GLOBAL[$arg]), and still the duplicate textarea field shows up.

    So, can you think of a generic (works for any theme) that can determine if the comment field has already been defined? And, if the duplicate is found, remove the one in the theme, so I can replace it with mine? Or is there a better way to ‘start over’ on the defining of fields in the comment form.

    I understand that the problem might be caused by bad coding practices on the theme, but would like to find a workaround so a theme doesn’t change the fields I want on the comment form.

    Thanks….Rick…

    Reply

Leave a Reply

(will not be published)