The WordPress function comment_form() is used for generating commenting form within WordPress theme. The great thing about this function is that it has wide range of parameters you can use to perform fine tuning. You could do something as simple as changing the wording (“Leave a reply”), or you could also create advanced layouts. For example, why would you have author and email input fields both in single line, given that in wider layouts on higher resolutions commenter will not fill even 50% of the input field?
As for available parameters, if you check official WordPress documentation, you will find the following:
- ‘fields’ (array) { Default comment fields, filterable by default via the ‘comment_form_default_fields’ hook.
- ‘author’ (string) Comment author field HTML.
- ’email’ (string) Comment author email field HTML.
- ‘url’ (string) Comment author URL field HTML. }
- …and many others.
Most of these can be changed only by adding new items into functions’ array, such as (make sure you include text domain for translation purposes):
1 2 3 4 |
comment_form(array( 'label_submit' => __('Post my Comment', 'bbird-under'), 'title_reply' => __('Have something to say?', 'bbird-under'), )); |
But if you look at the list of parameters closely, you’ll find ‘fields’ => $fields. You may omit this one at first, but as it turns out, this could be the most important parameter for any advanced layout change. Let’s check on how it looks like and WordPress core:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
function comment_form( $args = array(), $post_id = null ) { ... $commenter = wp_get_current_commenter(); $user = wp_get_current_user(); $user_identity = $user->exists() ? $user->display_name : ''; ... $req = get_option( 'require_name_email' ); $aria_req = ( $req ? " aria-required='true'" : '' ); $html_req = ( $req ? " required='required'" : '' ); $html5 = 'html5' === $args['format']; $fields = array( 'author' => '<p class="comment-form-author">' . '<label for="author">' . __( 'Name' ) . ( $req ? ' <span class="required">*</span>' : '' ) . '</label> ' . '<input id="author" name="author" type="text" value="' . esc_attr( $commenter['comment_author'] ) . '" size="30"' . $aria_req . $html_req . ' /></p>', 'email' => '<p class="comment-form-email"><label for="email">' . __( 'Email' ) . ( $req ? ' <span class="required">*</span>' : '' ) . '</label> ' . ... $fields = apply_filters( 'comment_form_default_fields', $fields ); ... $defaults = array( 'fields' => $fields, 'comment_field' => '<p class="comment-form-comment"><label for="comment">' . _x( 'Comment', 'noun' ) . '</label> <textarea id="comment" name="comment" cols="45" rows="8" aria-describedby="form-allowed-tags" aria-required="true" required="required"></textarea></p>', ... |
By the quick look, $fields array is what does the magic – if determines how the layout of default form will look like. Also, in order to avoid PHP warnings and notices (undeclared variable), you will also need to redeclare $req, $aria_req, etc.
Finally, this is how it would look like implemented into comments.php template file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?php $commenter = wp_get_current_commenter(); $req = get_option('require_name_email'); $aria_req = ($req ? " aria-required='true'" : ''); $html_req = ($req ? " required='required'" : ''); $html5 = 'html5'; $fields = array( 'author' => '<div class="row"><div class="medium-6 columns"><p class="comment-form-author">' . '<label for="author">' . __('Name', 'bbird-under') . ($req ? ' <span class="required">*</span>' : '') . '</label> ' . '<input id="author" name="author" type="text" value="' . esc_attr($commenter['comment_author']) . '" size="30"' . $aria_req . $html_req . ' /></p></div>', 'email' => '<div class="medium-6 columns"><p class="comment-form-email"><label for="email">' . __('Email', 'bbird-under') . ($req ? ' <span class="required">*</span>' : '') . '</label> ' . '<input id="email" name="email" ' . ($html5 ? 'type="email"' : 'type="text"') . ' value="' . esc_attr($commenter['comment_author_email']) . '" size="30" aria-describedby="email-notes"' . $aria_req . $html_req . ' /></p></div></div>', 'url' => '<p class="comment-form-url"><label for="url">' . __('Website', 'bbird-under') . '</label> ' . '<input id="url" name="url" ' . ($html5 ? 'type="url"' : 'type="text"') . ' value="' . esc_attr($commenter['comment_author_url']) . '" size="30" /></p>' ); comment_form(array( 'fields' => $fields, 'label_submit' => __('Post my Comment', 'bbird-under'), 'title_reply' => __('Have something to say?', 'bbird-under'), 'title_reply_to' => __('Respond to %s', 'bbird-under'), 'comment_notes_before' => '<p class="comment-notes"><span id="email-notes">' . __('(No worries, we will keep your email safe! Also, make sure you fill in email and name fields before posting a comment.)', 'bbird-under') . '</span></p>' )); ?> </div> |
BUT, if you were careless as I was, you likely omitted the fact that $fields is filterable via ‘comment_form_default_fields’ hook. If unsure how to use filters, check on my quick tutorial.
Implementation through filters is easy and would look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
function bbird_under_comment_form_layout ($fields) { $commenter = wp_get_current_commenter(); $req = get_option('require_name_email'); $aria_req = ($req ? " aria-required='true'" : ''); $html_req = ($req ? " required='required'" : ''); $html5 = 'html5'; $fields = array( 'author' => '<div class="row"><div class="medium-6 columns"><p class="comment-form-author">' . '<label for="author">' . __('Name', 'bbird-under') . ($req ? ' <span class="required">*</span>' : '') . '</label> ' . '<input id="author" name="author" type="text" value="' . esc_attr($commenter['comment_author']) . '" size="30"' . $aria_req . $html_req . ' /></p></div>', 'email' => '<div class="medium-6 columns"><p class="comment-form-email"><label for="email">' . __('Email', 'bbird-under') . ($req ? ' <span class="required">*</span>' : '') . '</label> ' . '<input id="email" name="email" ' . ($html5 ? 'type="email"' : 'type="text"') . ' value="' . esc_attr($commenter['comment_author_email']) . '" size="30" aria-describedby="email-notes"' . $aria_req . $html_req . ' /></p></div></div>', 'url' => '<p class="comment-form-url"><label for="url">' . __('Website', 'bbird-under') . '</label> ' . '<input id="url" name="url" ' . ($html5 ? 'type="url"' : 'type="text"') . ' value="' . esc_attr($commenter['comment_author_url']) . '" size="30" /></p>' ); return $fields; } add_filter( 'comment_form_default_fields', 'bbird_under_comment_form_layout' ); |
While our comment_form function call would look like this:
1 2 3 4 5 6 7 8 |
<?php comment_form(array( 'label_submit' => __('Post my Comment', 'bbird-under'), 'title_reply' => __('Have something to say?', 'bbird-under'), 'title_reply_to' => __('Respond to %s', 'bbird-under'), 'comment_notes_before' => '<p class="comment-notes"><span id="email-notes">' . __('(No worries, we will keep your email safe! Also, make sure you fill in email and name fields before posting a comment.)', 'bbird-under') . '</span></p>' )); ?> |
Both approaches seem to be working, but given that WordPress core developers added filter here, conclusion is simple – use filter!