Move the WordPress comment form above the comment list

On one of the Divi Facebook groups I’m a member of, where I try and answer questions people pose about Divi and WordPress, someone asked how they could move the WordPress comment form above the comment list on their website’s posts, something I’d never been asked to do before.

In the image below you can see how the comment form sits underneath any comments on posts by default. As you can imagine, if there are a lot of comments, some users may not take the time to scroll to the bottom of the list to use the form, especially if they’re viewing the website on their phone.

Default Comment Form Position

One way around this is to enabled paged comments in the “Settings” ⟶ “Discussion” ⟶ “Other comment settings” settings section of your website. Here you can specify how many comments are displayed per page, and in what order. See the image below.

Other comment settings

You could set the number reasonably low to ensure there wasn’t a long scroll to get to the comment form. But, this isn’t what was asked.

So, putting my thinking cap on I had a good old ponder on how best this could be done, both for WordPress in general and also for the specific case where they were using the Divi comments module in the Divi Theme Builder.

I was really hoping that one solution would work for both cases, i.e. the general WordPress solution, but sadly that wasn’t the case. You can see both solutions below so depending on how you’re creating your WordPress posts, one of these should do the job if you want to move the comment form above the comment list.

General WordPress solution

In case you weren’t aware, WordPress has had a feature called child themes for a very long time now. Setting up a child theme gives you the ability to easily add your own code/CSS to your website, and it also allows you to override parent theme page templates and the like.

This is how we’re going to change the position of the default post comment form position, and assumes that you’ve already set up a child theme on your Divi website.

1. The Divi comments.php file

If you look in the Divi theme folder (typically wp-content/themes/Divi) you’ll see a whole bunch of files related to the Divi theme. The one we’re interested in for this tutorial is called “comments.php”.

Divi Theme Files

2. Copy the comments.php file

The first thing you need to do is copy the original Divi comments.php file into your child theme’s folder. How you do this is entirely up to you, but I use an FTP client to connect to the server and download/upload the file to its new location.

3. Edit the comments.php file

At the time of writing, the default Divi comments.php file contains the following:

<?php
	if ( post_password_required() ) : ?>

<p class="nocomments container"><?php esc_html_e( 'This post is password protected. Enter the password to view comments.', 'Divi' ); ?></p>
<?php
		return;
	endif;
?>

<?php
if ( empty( $comments_by_type ) ) {
	$comments_by_type = separate_comments( $comments );
}
?>

<section id="comment-wrap">
<?php if ( have_comments() && ! empty( $comments_by_type['comment'] ) ) : ?>
	<h1 id="comments" class="page_title"><?php comments_number( esc_html__( '0 Comments', 'Divi' ), esc_html__( '1 Comment', 'Divi' ), '% ' . esc_html__( 'Comments', 'Divi' ) ); ?></h1>
<?php endif; ?>
	<?php if ( have_comments() ) : ?>
		<?php if ( get_comment_pages_count() > 1 && get_option( 'page_comments' ) ) : // Are there comments to navigate through? ?>
			<div class="comment_navigation_top clearfix">
				<div class="nav-previous"><?php previous_comments_link( et_get_safe_localization( __( '<span class="meta-nav">←</span> Older Comments', 'Divi' ) ) ); ?></div>
				<div class="nav-next"><?php next_comments_link( et_get_safe_localization( __( 'Newer Comments <span class="meta-nav">→</span>', 'Divi' ) ) ); ?></div>
			</div>
		<?php endif; // check for comment navigation ?>

		<?php if ( ! empty($comments_by_type['comment']) ) : ?>
			<ol class="commentlist clearfix">
				<?php wp_list_comments( array('type'=>'comment','callback'=>'et_custom_comments_display') ); ?>
			</ol>
		<?php endif; ?>

		<?php if ( get_comment_pages_count() > 1 && get_option( 'page_comments' ) ) : // Are there comments to navigate through? ?>
			<div class="comment_navigation_bottom clearfix">
				<div class="nav-previous"><?php previous_comments_link( et_get_safe_localization( __( '<span class="meta-nav">←</span> Older Comments', 'Divi' ) ) ); ?></div>
				<div class="nav-next"><?php next_comments_link( et_get_safe_localization( __( 'Newer Comments <span class="meta-nav">→</span>', 'Divi' ) ) ); ?></div>
			</div>
		<?php endif; // check for comment navigation ?>

		<?php if ( ! empty($comments_by_type['pings']) ) : ?>
			<div id="trackbacks">
				<h3 id="trackbacks-title"><?php esc_html_e('Trackbacks/Pingbacks','Divi'); ?></h3>
				<ol class="pinglist">
					<?php wp_list_comments('type=pings&callback=et_list_pings'); ?>
				</ol>
			</div>
		<?php endif; ?>
	<?php else : // this is displayed if there are no comments so far ?>
	   <div id="comment-section" class="nocomments">
		  <?php if ('open' === $post->comment_status) : ?>

		  <?php else : // comments are closed ?>

		  <?php endif; ?>
	   </div>
	<?php endif; ?>
	<?php if ('open' === $post->comment_status) : ?>
		<?php comment_form( array('label_submit' => esc_attr__( 'Submit Comment', 'Divi' ), 'title_reply' => '<span>' . esc_attr__( 'Submit a Comment', 'Divi' ) . '</span>', 'title_reply_to' => esc_attr__( 'Leave a Reply to %s', 'Divi' ), 'class_submit' => 'submit et_pb_button' ) ); ?>
	<?php else: ?>

	<?php endif; // if you delete this the sky will fall on your head ?>
</section>

The bit that creates the comment form is:

<?php if ('open' === $post->comment_status) : ?>
	<?php comment_form( array('label_submit' => esc_attr__( 'Submit Comment', 'Divi' ), 'title_reply' => '<span>' . esc_attr__( 'Submit a Comment', 'Divi' ) . '</span>', 'title_reply_to' => esc_attr__( 'Leave a Reply to %s', 'Divi' ), 'class_submit' => 'submit et_pb_button' ) ); ?>
<?php else: ?>

<?php endif; // if you delete this the sky will fall on your head ?>

This checks to make sure that comments are open on the current post, and if they are it then calls the “comment_form” functions with a number of settings to create and display the comment form.

Note: If you’re using the default comment form described here, you can edit the options to easily change such things as the submit button text, the button class, and other text used in the form.

In order to move the comment form above the comments, all we need to do is move that piece of code above the bit that generates the list of comments in the file, save it and – if necessary, depending on how you edited the file – upload the updated version to the child theme folder.

Below is the final updated contents of the comments.php file:

<?php
	if ( post_password_required() ) : ?>

<p class="nocomments container"><?php esc_html_e( 'This post is password protected. Enter the password to view comments.', 'Divi' ); ?></p>
<?php
		return;
	endif;
?>

<?php
if ( empty( $comments_by_type ) ) {
	$comments_by_type = separate_comments( $comments );
}
?>

<section id="comment-wrap">
<?php if ( have_comments() && ! empty( $comments_by_type['comment'] ) ) : ?>
	<h1 id="comments" class="page_title"><?php comments_number( esc_html__( '0 Comments', 'Divi' ), esc_html__( '1 Comment', 'Divi' ), '% ' . esc_html__( 'Comments', 'Divi' ) ); ?></h1>
<?php endif; ?>
	<?php if ('open' === $post->comment_status) : ?>
		<?php comment_form( array('label_submit' => esc_attr__( 'Submit Comment', 'Divi' ), 'title_reply' => '<span>' . esc_attr__( 'Submit a Comment', 'Divi' ) . '</span>', 'title_reply_to' => esc_attr__( 'Leave a Reply to %s', 'Divi' ), 'class_submit' => 'submit et_pb_button' ) ); ?>
	<?php else: ?>

	<?php endif; // if you delete this the sky will fall on your head ?>
	<?php if ( have_comments() ) : ?>
		<?php if ( get_comment_pages_count() > 1 && get_option( 'page_comments' ) ) : // Are there comments to navigate through? ?>
			<div class="comment_navigation_top clearfix">
				<div class="nav-previous"><?php previous_comments_link( et_get_safe_localization( __( '<span class="meta-nav">←</span> Older Comments', 'Divi' ) ) ); ?></div>
				<div class="nav-next"><?php next_comments_link( et_get_safe_localization( __( 'Newer Comments <span class="meta-nav">→</span>', 'Divi' ) ) ); ?></div>
			</div>
		<?php endif; // check for comment navigation ?>

		<?php if ( ! empty($comments_by_type['comment']) ) : ?>
			<ol class="commentlist clearfix">
				<?php wp_list_comments( array('type'=>'comment','callback'=>'et_custom_comments_display') ); ?>
			</ol>
		<?php endif; ?>

		<?php if ( get_comment_pages_count() > 1 && get_option( 'page_comments' ) ) : // Are there comments to navigate through? ?>
			<div class="comment_navigation_bottom clearfix">
				<div class="nav-previous"><?php previous_comments_link( et_get_safe_localization( __( '<span class="meta-nav">←</span> Older Comments', 'Divi' ) ) ); ?></div>
				<div class="nav-next"><?php next_comments_link( et_get_safe_localization( __( 'Newer Comments <span class="meta-nav">→</span>', 'Divi' ) ) ); ?></div>
			</div>
		<?php endif; // check for comment navigation ?>

		<?php if ( ! empty($comments_by_type['pings']) ) : ?>
			<div id="trackbacks">
				<h3 id="trackbacks-title"><?php esc_html_e('Trackbacks/Pingbacks','Divi'); ?></h3>
				<ol class="pinglist">
					<?php wp_list_comments('type=pings&callback=et_list_pings'); ?>
				</ol>
			</div>
		<?php endif; ?>
	<?php else : // this is displayed if there are no comments so far ?>
	   <div id="comment-section" class="nocomments">
		  <?php if ('open' === $post->comment_status) : ?>

		  <?php else : // comments are closed ?>

		  <?php endif; ?>
	   </div>
	<?php endif; ?>
</section>

And this is the end result using the updated comments.php file:

Moved Comment Form

Divi Theme Builder solution

As mentioned previously, Divi has a Theme Builder, where you can create templates for pages, posts, products etc. When someone loads a post (for example) that uses one of these templates, Divi dynamically creates the post using the modules in the template, in this example, the post content module and the comments module.

1. The Theme Builder Template

Creating a template is very easy to do. Go to “Divi” ⟶ “Theme Builder” ⟶ “Add New Template” ⟶ “Build New Template” ⟶ “Posts” ⟶ “All Posts” ⟶ “Create Template”.

You’ll then need to select “Add Custom Body” ⟶ “Build Custom Body”.

Edit the custom body and create the template using the required modules etc. The following shows a very simple posts template, both in its wireframe view and visual builder view:

Edit the custom body and create the template using the required modules/design. the following shows a very simple posts template, both in its wireframe view and visual builder view:

Theme Builder Template Wireframe
Theme Builder Template Visual

Save the theme and make sure you select “Save Changes” in the main Theme Builder page, otherwise your new template won’t be active.

And this is what a post looks like using the created theme template:

Default Theme Builder Post

2. JavaScript to move the comment form

Unless you want to create your own comments module for Divi (creating a custom module isn’t something I’ve gotten round to trying yet) there was only one way I could think of to move the comments form, and that was with a little sprinkling of JavaScript to do the job for me.

After a little bit of scratching of the ol’ noodle, I came up with the following:

<script>
jQuery(function($) {
	$('#respond').each(function () {
		if (!$(this).text().match(/^s*$/)) {
    		$(this).insertBefore($(this).prev('.commentlist'));
    		}
	});
});

</script>

Before we get into what the code’s doing, it’s important to mention that this uses the comment form ID and comment list class to ensure we’re moving the right things about. So, if you’ve never inspected a post’s source before, these are “#respond” and “.commentlist” respectively.

With that out of the way, let’s break down what this is doing:

  1. Select every element with the ID “respond”; there should only be one but this guards against there being multiple comment forms…you never know
  2. With “.each” we can iterate through each of those elements and apply a function to them, in which the element is selected with $(this)
  3. With “!$(this).text().match(/^\s*$/)” you get true when the element from the current iteration has no spaces
  4. With “$(this).insertBefore($(this).prev(‘.commentlist’))” you insert the element before the element in brackets, which is the element with class “commentlist” that is directly before the element itself

So pretty simple really…I guess? Ultimately you just need to know that it takes the element with the comment form in it, and moves this before the element with the comment list in.

You can add the code to the theme template using a code module (this means it’ll only ever be added to posts on your website), giving you the following result:

Updated Theme Builder Post

And We’re Done

Here I’ve shown you two different ways to move the comment form above the comment list, covering both a general WordPress solution and a Divi-specific solution for people using the Theme Builder to create a post template.