How to Build Standard WordPress Comment Templates for Seamless WooCommerce Integrations
Understanding WordPress and WooCommerce Comment Template Hierarchy
WordPress employs a template hierarchy to determine which template file to load for a given page. For comments, this primarily involves comments.php. However, when WooCommerce is active, it introduces its own template overrides, particularly for product pages. While WooCommerce doesn’t directly replace the core comments.php for standard blog posts, it significantly influences how comments are displayed on product pages. Understanding this hierarchy is crucial for ensuring consistent comment display across your site, whether it’s a blog post or a product.
The default WordPress comment template is typically found in your theme’s root directory as comments.php. This file handles the display of comments, the comment form, and pagination. WooCommerce, on the other hand, uses its own template files, often located within the woocommerce/templates/ directory. For product pages, it leverages single-product.php and related template parts. When you want to customize comment display on product pages, you’ll often be working within the context of WooCommerce’s template structure, but still referencing the underlying WordPress comment functions.
Creating a Standard comments.php Template
Before integrating with WooCommerce, it’s essential to have a robust, standard comments.php file in your theme. This file serves as the foundation for all comment displays. Here’s a breakdown of a typical, well-structured comments.php:
comments.php Structure and Key Functions
A standard comments.php file will typically include:
- A conditional check to see if comments are open and available.
- A function to list comments (
wp_list_comments()). - A function to display the comment form (
comment_form()). - Comment pagination if there are many comments.
Here’s a practical example of a comments.php file that you can adapt:
Example comments.php
<?php
/**
* The template for displaying comments.
*
* This file contains the closing of the "container" div and everything up to the "site-content" div.
*
* @package WordPress
* @subpackage Twenty_Twenty_One
* @since Twenty Twenty-One 1.0
*/
/*
* If the current post is protected by a password and
* the visitor has not yet entered the password,
* return early without attempting to display the comments.
*/
if ( post_password_required() ) {
return;
}
$twenty_twenty_one_comment_count = get_comments_number();
?>
<div id="comments" class="comments-area">
<?php
if ( have_comments() ) :
?>
<h2 class="comments-title">
<?php
$twenty_twenty_one_comment_number = get_comments_number();
if ( 1 === $twenty_twenty_one_comment_number ) {
/* translators: %s: translates a singular comment count */
printf( esc_html__( 'One thought on “%s”', 'twenty-twenty-one' ), get_the_title() );
} else {
/* translators: 1: number of comments, 2: translates a plural comment count */
printf( esc_html( _n( '%1$s thought on “%2$s”', '%1$s thoughts on “%2$s”', (int) $twenty_twenty_one_comment_number, 'twenty-twenty-one' ) ), number_format_i18n( $twenty_twenty_one_comment_number ), get_the_title() );
}
?>
</h2>
<?php
the_comments_navigation();
// Custom callback for listing comments.
wp_list_comments(
array(
'style' => 'ol',
'short_ping' => true,
'avatar_size' => 40,
'callback' => 'twenty_twenty_one_comment_callback', // Assuming a theme-specific callback.
)
);
the_comments_navigation();
endif; // Check for have_comments().
// If comments are closed and there are no comments, let's leave the comments section empty.
if ( ! comments_open() && get_comments_number() && post_type_supports( get_post_type(), 'comments' ) ) :
?>
<p class="no-comments"><?php esc_html_e( 'Comments are closed.', 'twenty-twenty-one' ); ?></p>
<?php
endif;
comment_form(
array(
'title_reply' => esc_html__( 'Leave a comment', 'twenty-twenty-one' ),
'title_reply_before' => '<h2 id="reply-title" class="comment-reply-title">',
'title_reply_after' => '</h2>',
)
);
?>
</div><!-- #comments -->
In this example, twenty_twenty_one_comment_callback is a placeholder for a theme-specific function that controls the HTML structure of individual comments. If your theme doesn’t have one, WordPress will use its default output. The comment_form() function is highly customizable; you can pass arguments to change its title, labels, and more.
WooCommerce Product Page Comment Integration
WooCommerce typically displays product reviews separately from standard comments. However, you might want to unify these or ensure your standard comment template is respected. On product pages, WooCommerce uses its own template structure, often overriding the default WordPress single post template. The key is to understand how WooCommerce hooks into the WordPress comment system and how to leverage its template overrides.
Overriding WooCommerce Templates for Comments
To customize how comments appear on WooCommerce product pages, you’ll need to override WooCommerce’s templates. The relevant template for product reviews is usually found within WooCommerce’s core files, but the display logic often relies on WordPress’s comment functions.
The process involves:
- Copying the relevant WooCommerce template file into your theme’s directory structure.
- Modifying it to integrate with your standard comment display logic.
WooCommerce uses a system of template files that can be overridden by placing them in your theme’s directory at your-theme/woocommerce/templates/. For product reviews, the primary template is often single-product.php, which then includes other template parts. However, the actual comment display logic within product pages often relies on the standard WordPress comment functions, especially if you’re not using WooCommerce’s dedicated review system.
Leveraging comments.php on Product Pages
By default, WooCommerce product pages might not directly call your theme’s comments.php for standard comments. Instead, they have their own review system. If you want to use your theme’s comments.php for product pages (perhaps for a custom post type that is also a product, or if you’re disabling WooCommerce reviews), you’ll need to ensure the product template correctly calls the comment functions.
A common approach is to ensure that your theme’s single-product.php (if you’ve created one to override WooCommerce’s default) or a relevant template part includes a call to comments_template(). This function is WordPress’s standard way of including the comment template.
Example: Modifying single-product.php
If you’ve copied single-product.php from WooCommerce into your theme (your-theme/woocommerce/single-product.php), you can modify it to include your standard comment template. Locate the section where reviews or comments are displayed and ensure it calls comments_template().
<?php
/**
* The Template for displaying product archives, including the main shop page which is a post type archive.
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package WooCommerce\Templates
*/
defined( 'ABSPATH' ) || exit;
get_header( 'shop' );
/**
* Hook: woocommerce_before_main_content.
*
* @hooked woocommerce_output_content_wrapper - 10 (outputs opening divs for the content area)
* @hooked woocommerce_breadcrumb - 20
* @hooked WC_Structured_Data::generate_product_schema() - 30 - Deprecated. Use woocommerce_shop_loop.
*/
do_action( 'woocommerce_before_main_content' );
?>
<?php if ( wc_get_loop_prop( 'total' ) ) : ?>
<?php
/**
* Hook: woocommerce_before_shop_loop.
*
* @hooked woocommerce_output_all_notices - 10
* @hooked woocommerce_result_count - 20
* @hooked woocommerce_catalog_ordering - 30
* @hooked woocommerce_ செய்யவும்_per_page - 40
*/
do_action( 'woocommerce_before_shop_loop' );
woocommerce_product_loop();
?>
<?php else : ?>
<?php
/**
* Hook: woocommerce_no_products_found.
*/
do_action( 'woocommerce_no_products_found' );
?>
<?php endif; ?>
<?php
/**
* Hook: woocommerce_after_main_content.
*
* @hooked woocommerce_output_content_wrapper_end - 10 (outputs closing divs for the content area)
*/
do_action( 'woocommerce_after_main_content' );
// --- MODIFICATION STARTS HERE ---
// This section is typically where product details are displayed.
// To integrate standard comments, you might add this block.
// Ensure this is placed logically, perhaps after the product content or related products.
// Check if comments are enabled for products (if using a custom post type or a plugin that enables them).
// For standard WooCommerce products, reviews are handled differently.
// If you want to use the standard WP comment system on products, you might need to:
// 1. Disable WooCommerce's built-in reviews.
// 2. Ensure comments are enabled for the 'product' post type.
// 3. Then, call comments_template().
if ( comments_open() || get_comments_number() ) {
comments_template(); // This will load your theme's comments.php
}
// --- MODIFICATION ENDS HERE ---
get_footer( 'shop' );
Important Note: Directly calling comments_template() on a standard WooCommerce product page will likely display the standard WordPress comments, not WooCommerce product reviews. If your goal is to unify reviews and comments, you’ll need a more advanced solution, potentially involving custom post types or plugins that bridge this gap. However, if you’re using custom post types that are products and want standard WordPress comments, this is the way to integrate.
Styling Comments and Forms
Once you have your comments.php template correctly integrated, you’ll want to style it to match your theme. This involves adding CSS rules to your theme’s style.css file.
CSS Selectors for Comments
Key elements to target include:
.comments-area: The main container for the comments section..comment-list: The unordered or ordered list containing comments..comment: Individual comment entries..comment-author: The commenter’s name..comment-meta: Timestamp and permalink..comment-content: The actual comment text..comment-form: The comment form container..comment-form label: Labels for form fields..comment-form input[type="text"],.comment-form input[type="email"],.comment-form textarea: Form fields..form-submit input[type="submit"]: The submit button.
Example CSS
/* comments.php styling */
.comments-area {
margin-top: 40px;
padding-top: 20px;
border-top: 1px solid #eee;
}
.comments-title {
font-size: 1.8em;
margin-bottom: 30px;
}
.comment-list {
list-style: none;
padding: 0;
margin: 0;
}
.comment {
margin-bottom: 30px;
padding-bottom: 20px;
border-bottom: 1px solid #eee;
display: flex;
align-items: flex-start; /* Align items to the top */
}
.comment .avatar {
margin-right: 15px;
border-radius: 50%; /* Make avatars circular */
width: 50px; /* Explicitly set avatar width */
height: 50px; /* Explicitly set avatar height */
flex-shrink: 0; /* Prevent avatar from shrinking */
}
.comment-body {
flex-grow: 1; /* Allow comment body to take available space */
}
.comment-author {
font-weight: bold;
margin-bottom: 5px;
}
.comment-meta {
font-size: 0.9em;
color: #777;
margin-bottom: 10px;
}
.comment-content p {
margin-bottom: 10px;
line-height: 1.6;
}
.comment-reply-link {
font-size: 0.9em;
text-decoration: none;
color: #0073aa;
}
.comment-reply-link:hover {
text-decoration: underline;
}
/* Comment Form Styling */
.comment-form {
margin-top: 40px;
padding-top: 20px;
border-top: 1px solid #eee;
}
.comment-form label {
display: block;
margin-bottom: 10px;
font-weight: bold;
}
.comment-form input[type="text"],
.comment-form input[type="email"],
.comment-form input[type="url"],
.comment-form textarea {
width: 100%;
padding: 10px;
margin-bottom: 15px;
border: 1px solid #ddd;
box-sizing: border-box; /* Include padding and border in the element's total width and height */
}
.comment-form textarea {
min-height: 150px;
resize: vertical;
}
.form-submit {
margin-top: 20px;
}
.form-submit input[type="submit"] {
background-color: #0073aa;
color: white;
padding: 12px 20px;
border: none;
cursor: pointer;
font-size: 1em;
border-radius: 4px;
transition: background-color 0.3s ease;
}
.form-submit input[type="submit"]:hover {
background-color: #005177;
}
/* Responsive adjustments */
@media (max-width: 768px) {
.comment {
flex-direction: column;
align-items: center;
text-align: center;
}
.comment .avatar {
margin-right: 0;
margin-bottom: 15px;
}
}
Remember to enqueue your theme’s stylesheet correctly using wp_enqueue_style() in your theme’s functions.php file.
Advanced Considerations: Custom Comment Callbacks and AJAX
For more advanced control, you can define custom callback functions for wp_list_comments(). This allows you to completely dictate the HTML output for each comment.
Custom Comment Callback Example
function my_custom_comment_callback( $comment, $args, $depth ) {
$GLOBALS['comment'] = $comment;
?>
<li id="comment-<?php comment_ID(); ?>" <?php comment_class( empty( $args['toplevel_comment'] ) ? 'comment' : 'comment parent' ); ?>>
<article id="div-comment-<?php comment_ID(); ?>" class="comment-body">
<footer class="comment-meta">
<div class="comment-author vcard">
<?php
if ( 0 != $comment->user_id ) {
printf( '<b class="fn">%s</b>', get_comment_author_link() );
} else {
echo get_comment_author_link();
}
?>
<span class="says"></span>
</div><!-- .comment-author .vcard -->
<div class="comment-metadata">
<a href="<?php echo esc_url( get_comment_link( $comment->comment_ID ) ); ?>">
<time datetime="<?php comment_time( 'c' ); ?>">
<?php printf( esc_html__( '%1$s at %2$s', 'your-theme-textdomain' ), get_comment_date(), get_comment_time() ); ?>
</time>
</a>
<?php edit_comment_link( esc_html__( 'Edit', 'your-theme-textdomain' ), '<span class="edit-link">', '</span>' ); ?>
</div><!-- .comment-metadata -->
<?php if ( $comment->comment_approved == '0' ) : ?>
<p class="comment-awaiting-moderation"><?php esc_html_e( 'Your comment is awaiting moderation.', 'your-theme-textdomain' ); ?></p>
<?php endif; ?>
</footer><!-- .comment-meta -->
<div class="comment-content">
<?php comment_text(); ?>
</div><!-- .comment-content -->
<div class="reply">
<?php
comment_reply_link(
array_merge(
$args,
array(
'add_below' => 'div-comment',
'depth' => $depth,
'max_depth' => $args['max_depth'],
)
)
);
?>
</div><!-- .reply -->
</article><!-- .comment-body -->
<?php // No closing here, as wp_list_comments() handles it.
}
To use this callback, you would modify your comments.php file:
// Inside your comments.php file, within the 'if ( have_comments() )' block:
wp_list_comments( array(
'style' => 'ol',
'callback' => 'my_custom_comment_callback', // Use your custom callback function
'avatar_size' => 60, // Example: adjust avatar size
) );
AJAX Comment Submission: For a smoother user experience, consider implementing AJAX for comment submission. This prevents a full page reload after a user submits a comment. WordPress has built-in support for AJAX comments, which can be enabled by adding a specific JavaScript file to your theme. You’ll typically need to enqueue a script that handles the AJAX request and response, often by hooking into wp_enqueue_scripts and using wp_localize_script to pass necessary data to your JavaScript.
Conclusion
Building standard WordPress comment templates for seamless WooCommerce integration involves understanding the template hierarchy, creating a robust comments.php, and knowing how to override WooCommerce templates when necessary. By leveraging WordPress’s built-in comment functions and applying custom styling and advanced techniques like custom callbacks, you can ensure a consistent and user-friendly comment experience across your entire site, including product pages.