Creating Your First Custom Standard WordPress Comment Templates in Multi-Language Site Networks
Understanding WordPress Comment Template Hierarchy
When WordPress renders comments on a post or page, it follows a specific template hierarchy. For single sites, this typically involves comments.php. However, in a multisite network, especially with internationalization, the default behavior might not suffice. We need to understand how WordPress resolves comment templates to effectively override them. The core function involved is locate_template(), which searches for a template file in the active theme and its parent theme. For comments, this often boils down to looking for comments.php, comments-template.php, or a specific template file passed to wp_list_comments().
Setting Up a Multisite Network for Localization
Before diving into custom templates, ensure your multisite network is correctly configured for multiple languages. This usually involves installing and activating a plugin like WPML or Polylang. For this guide, we’ll assume you’re using a standard WordPress multisite setup with language subdirectories or subdomains. The key is that each site within the network has its own language setting, which WordPress can leverage.
Creating a Basic Custom Comment Template
Let’s start by creating a custom comment template file. This file will contain the HTML structure for displaying individual comments and the comment form. We’ll place this file within our theme’s directory. For a multisite setup, it’s often best to use a child theme to avoid losing customizations during parent theme updates.
Create a new file named custom-comments.php in your active theme’s (or child theme’s) root directory. This file will house our custom comment display logic.
custom-comments.php Structure
Inside custom-comments.php, we’ll define the structure for each comment. WordPress provides the wp_list_comments() function, which is highly customizable. We’ll use its callback argument to specify our custom function for rendering each comment.
' . '
', 'url' => '' . '
', ); $args = array( 'id_form' => 'commentform', 'id_submit' => 'submit', 'class_submit' => 'submit', 'name_submit' => 'submit', 'title_reply' => __( 'Leave a Reply', 'your-text-domain' ), 'title_reply_to_set' => __( 'Leave a Reply to %s', 'your-text-domain' ), 'cancel_reply_link' => __( 'Cancel reply', 'your-text-domain' ), 'label_submit' => __( 'Post Comment', 'your-text-domain' ), 'comment_field' => '', 'must_log_in' => '' . sprintf( __( 'You must be %1$s to post a comment.', 'your-text-domain' ), '' . __( 'logged in', 'your-text-domain' ) . '' ) . '
', 'logged_in_as' => '' . sprintf( __( 'Logged in as %1$s. Log out?', 'your-text-domain' ), $user_identity, esc_url( wp_logout_url( apply_filters( 'the_permalink', get_permalink() ) ) ) ) . '
', 'fields' => apply_filters( 'comment_form_default_fields', $fields ), 'comment_notes_before' => '' . __( 'Your email address will not be published.', 'your-text-domain' ) . ( $req ? ' ' . __( 'Required fields are marked', 'your-text-domain' ) . ' *' : '' ) . '
', 'comment_notes_after' => '', 'action' => site_url( '/wp-comments-post.php' ), ); comment_form( $args ); } ?>Integrating the Custom Template in Multisite
Now, we need to tell WordPress to use our custom-comments.php file. The standard way to do this is by modifying your theme’s comments.php file. However, for a multisite network, we want to conditionally load this template based on the current site’s language or ID.
Modifying comments.php
Open your theme’s (or child theme’s) comments.php file. If it doesn’t exist, create it. We’ll add logic to include our custom template conditionally.
'custom-comments-en.php', // Example for English
'fr-FR' => 'custom-comments-fr.php', // Example for French
// Add more languages and their corresponding template files as needed.
);
// Determine which template to load.
$comment_template_to_load = 'custom-comments.php'; // Default template
if ( isset( $language_template_map[ $current_language ] ) ) {
$custom_template_file = $language_template_map[ $current_language ];
// Check if the custom template file exists in the theme.
if ( file_exists( get_template_directory() . '/' . $custom_template_file ) ) {
$comment_template_to_load = $custom_template_file;
} elseif ( file_exists( get_stylesheet_directory() . '/' . $custom_template_file ) ) {
$comment_template_to_load = $custom_template_file;
}
}
// Check if the determined template file exists.
if ( file_exists( get_template_directory() . '/' . $comment_template_to_load ) ) {
include get_template_directory() . '/' . $comment_template_to_load;
} elseif ( file_exists( get_stylesheet_directory() . '/' . $comment_template_to_load ) ) {
include get_stylesheet_directory() . '/' . $comment_template_to_load;
} else {
// Fallback to default WordPress comment handling if no custom template is found.
// This part might need adjustment based on your theme's structure.
// If your theme doesn't have a default comments.php, you might need to include a basic one.
if ( file_exists( get_template_directory() . '/comments-default.php' ) ) {
include get_template_directory() . '/comments-default.php';
} elseif ( file_exists( get_stylesheet_directory() . '/comments-default.php' ) ) {
include get_stylesheet_directory() . '/comments-default.php';
} else {
// As a last resort, include the default WordPress comments template if it exists.
// This is unlikely to be the case if you're creating a custom theme.
// You might need to implement a basic fallback here if your theme lacks one.
echo '' . __( 'Comments are closed.', 'your-text-domain' ) . '
';
}
}
?>
In this modified comments.php:
- We retrieve the current site’s language using
get_bloginfo( 'language' ). - A
$language_template_maparray is defined to associate specific languages with their corresponding custom comment template files (e.g.,custom-comments-en.php,custom-comments-fr.php). - We check if the current language exists in the map. If it does, we attempt to load the specified custom template file.
- If no language-specific template is found, a default
custom-comments.phpis used. - The code includes checks for both the parent theme (
get_template_directory()) and the child theme (get_stylesheet_directory()) to ensure compatibility. - A fallback mechanism is included, though you might need to tailor this to your theme’s specific structure.
Creating Language-Specific Comment Templates
Based on the $language_template_map in the modified comments.php, you’ll need to create files like custom-comments-en.php and custom-comments-fr.php in your theme’s directory. These files will contain the actual HTML and PHP for rendering comments and the form for each specific language.
Example: custom-comments-fr.php
This file would be very similar to custom-comments.php, but with French translations for strings.
' . '
', 'url' => '' . '
', ); $args = array( 'id_form' => 'commentform', 'id_submit' => 'submit', 'class_submit' => 'submit', 'name_submit' => 'submit', 'title_reply' => __( 'Laisser un commentaire', 'your-text-domain' ), // French for "Leave a Reply" 'title_reply_to_set' => __( 'Répondre à %s', 'your-text-domain' ), // French for "Reply to %s" 'cancel_reply_link' => __( 'Annuler la réponse', 'your-text-domain' ), // French for "Cancel reply" 'label_submit' => __( 'Poster le commentaire', 'your-text-domain' ), // French for "Post Comment" 'comment_field' => '', 'must_log_in' => '' . sprintf( __( 'Vous devez être %1$s pour poster un commentaire.', 'your-text-domain' ), '' . __( 'connecté', 'your-text-domain' ) . '' ) . '
', 'logged_in_as' => '' . sprintf( __( 'Connecté en tant que %1$s. Se déconnecter ?', 'your-text-domain' ), $user_identity, esc_url( wp_logout_url( apply_filters( 'the_permalink', get_permalink() ) ) ) ) . '
', 'fields' => apply_filters( 'comment_form_default_fields', $fields ), 'comment_notes_before' => '' . __( 'Votre adresse de messagerie ne sera pas publiée.', 'your-text-domain' ) . ( $req ? ' ' . __( 'Les champs obligatoires sont marqués', 'your-text-domain' ) . ' *' : '' ) . '
', 'comment_notes_after' => '', 'action' => site_url( '/wp-comments-post.php' ), ); comment_form( $args ); } // Call the appropriate functions based on the context. // In a real scenario, you'd call these within the main comments.php logic. // For demonstration, we'll assume these are called where needed. // For example, in the main comments.php, you might have: // if ( ! have_comments() ) : // // Display comment form // my_custom_comment_form_fr(); // else : // // Display comments list // wp_list_comments( array( 'callback' => 'my_custom_comment_callback_fr' ) ); // endif; ?>Advanced: Using Site ID for Template Selection
While language is a common differentiator, in complex multisite networks, you might need to use the specific Site ID (Blog ID) for template selection. This is particularly useful if certain sites have unique branding or functional requirements that go beyond simple language translation.
Modifying comments.php for Site ID
We can adapt the logic in comments.php to use the current site’s ID.
'custom-comments-main.php', // Example for the main site
5 => 'custom-comments-site5.php', // Example for site ID 5
12 => 'custom-comments-site12.php', // Example for site ID 12
// Add more site IDs and their corresponding template files.
);
// Determine which template to load.
$comment_template_to_load = 'custom-comments.php'; // Default template
if ( isset( $site_id_template_map[ $current_site_id ] ) ) {
$custom_template_file = $site_id_template_map[ $current_site_id ];
// Check if the custom template file exists in the theme.
if ( file_exists( get_template_directory() . '/' . $custom_template_file ) ) {
$comment_template_to_load = $custom_template_file;
} elseif ( file_exists( get_stylesheet_directory() . '/' . $custom_template_file ) ) {
$comment_template_to_load = $custom_template_file;
}
}
// Include the determined template file.
if ( file_exists( get_template_directory() . '/' . $comment_template_to_load ) ) {
include get_template_directory() . '/' . $comment_template_to_load;
} elseif ( file_exists( get_stylesheet_directory() . '/' . $comment_template_to_load ) ) {
include get_stylesheet_directory() . '/' . $comment_template_to_load;
} else {
// Fallback mechanism.
echo '' . __( 'Comments are closed.', 'your-text-domain' ) . '
';
}
?>
In this version:
- We use
get_current_blog_id()to fetch the ID of the current site in the network. - A
$site_id_template_mapis used to associate specific Site IDs with their custom comment template files. - The logic then attempts to load the template file corresponding to the current site’s ID, falling back to a default if no match is found.
Advanced Diagnostics: Troubleshooting Common Issues
When implementing custom comment templates in a multisite environment, several issues can arise. Here’s how to diagnose and resolve them:
Issue 1: Incorrect Template Loading
Symptom: The default comment template is always displayed, or an error occurs.
Diagnosis:
- Check File Paths: Double-check that the file paths in your
comments.php(e.g.,get_template_directory() . '/' . $custom_template_file) are correct and that the custom template files (e.g.,custom-comments-en.php) actually exist in the specified theme directory. - Verify Language/Site ID: Use a debugging plugin or add temporary
var_dump()statements in yourcomments.phpto confirm thatget_bloginfo( 'language' )orget_current_blog_id()are returning the expected values for the current site. - Theme Hierarchy Conflicts: Ensure there are no other plugins or theme functions interfering with template loading. Temporarily deactivate other plugins to rule them out.
- Child Theme Issues: If using a child theme, confirm that
get_stylesheet_directory()is correctly pointing to your child theme’s folder.
Issue 2: Comment Display Errors or Broken HTML
Symptom: Comments are not displayed correctly, or the page’s HTML structure is broken.
Diagnosis:
- Inspect HTML Output: Use your browser’s developer tools (Inspect Element) to examine the generated HTML for comments. Look for missing closing tags, incorrect attributes, or JavaScript errors related to comment rendering.
- Review Callback Function: Carefully review the `my_custom_comment_callback` function in your custom template file. Ensure all WordPress functions (like
comment_ID(),get_avatar(),comment_text()) are used correctly and that the HTML structure is valid. Pay close attention to the `comment_class()` output. - Check for PHP Errors: Enable WordPress debugging (by setting
WP_DEBUGtotrueinwp-config.php) and check the error logs for any PHP notices, warnings, or fatal errors originating from your custom comment template files. - Translation Issues: If you’re using translation functions like
__()or_e(), ensure the text domain (‘your-text-domain’) is correctly set and that your translation files (if any) are properly loaded.
Issue 3: Comment Form Not Submitting or Displaying
Symptom: The comment form is not appearing, or submitted comments are not saved or displayed.
Diagnosis:
- Verify
comment_form()Arguments: Ensure that the arguments passed to thecomment_form()function in your custom template are correctly formatted and that required fields are properly defined. - Check Form Action URL: The
'action'argument incomment_form()should point tosite_url( '/wp-comments-post.php' ). Verify this is correct. - User Permissions: Ensure that users have the necessary permissions to post comments. This is usually managed via WordPress settings and user roles.
- Spam Filters: Check your spam folder in the WordPress admin area or any anti-spam plugins you might be using. Comments can be filtered as spam.
- JavaScript Conflicts: Sometimes, JavaScript errors on the page can prevent the comment form from functioning correctly. Test with JavaScript disabled temporarily.
Issue 4: Multisite Specific Issues (e.g., Network Settings)
Symptom: Comments are disabled site-wide, or comment settings differ unexpectedly across sites.
Diagnosis:
- Network Admin Settings: Navigate to “Network Admin” -> “Settings” in your WordPress multisite dashboard. Check the “Default Settings” for comments. Ensure that “Allow people to post comments on new posts” is enabled if you intend for comments to be active.
- Site-Specific Settings: For each individual site within the network, go to “Settings” -> “Discussion”. Verify that comment settings are configured as desired for that specific site.
wp_site_options: In rare cases, network-wide comment settings might be stored in thewp_site_optionstable. Advanced users can inspect this table (e.g., using phpMyAdmin) for options related to comments.- Plugin Interference: Some network-activated plugins might override or manage comment settings. Check the settings of any network-wide plugins that could affect comments.