Can't override template - single-product-reviews.php

I’m not sure if this is a sage issue or a woocommerce issue, but I can’t seem to override the single-product-reviews.php template.

I copied and pasted it into views/woocommerce/single-product-reviews.blade.php as instructed, but none of the changes are showing through… I havn’t had this problem with any of the other templates, so I’m really not sure what’s going on with this one.

Any ideas?

After troubleshooting with some woocommerce people, and getting it to work in a non-sage theme, I’m fairly certain this issue has to do with sage… or at least how sage and woocommerce work together.

WooCommerce and blade templates do not work “out of the box” with Sage 9.

Add this package to your project and you should be good to go:

I already have it working properly using the sage-woo boilerplate. This particular template is the only one of the 20+ woocommerce templates I’ve created that isn’t working.

I also just tried it in a new sage theme w/ sage-woocommerce and I’m having the exact same issue… it’s not overriding.

@hambos22 Do you have any idea why I’m having these issues?

I think the guy in this post is on to something… That post was from 2013 though, and there’s a big difference between our workflows.

I was able to track down the functions he mentioned in class-wc-template-loader.php… can somebody please help me make sense of this and explain how / where to use it?

function comments_template_loader( $template ) {
    if ( get_post_type() !== 'product' ) {
        return $template;

    $check_dirs = array(
        trailingslashit( get_stylesheet_directory() ) . WC()->template_path(),
        trailingslashit( get_template_directory() ) . WC()->template_path(),
        trailingslashit( get_stylesheet_directory() ),
        trailingslashit( get_template_directory() ),
        trailingslashit( WC()->plugin_path() ) . 'templates/',

        $check_dirs = array( array_pop( $check_dirs ) );

    foreach ( $check_dirs as $dir ) {
        if ( file_exists( trailingslashit( $dir ) . 'single-product-reviews.php' ) ) {
            return trailingslashit( $dir ) . 'single-product-reviews.php';

add_filter( 'comments_template', array( __CLASS__, 'comments_template_loader' ) );

Any ideas anybody? This is driving me insane.

Hi. It’s unclear in your posts whether you’re using the sage-woocommerce package or some other Woocommerce solution. Can you clarify?

If it’s some other solution our ability to help on this forum will be limited, since we can only very effectively support the software we maintain here.

I see that you responded to the notification email which doesn’t post your reply here.

We actually need to know what code you’re using in order to troubleshoot the problem.

sage-woocommerce is a relatively recent addition to the Roots stable of projects but it’s become our best practice recommendation for integrating Woo and Sage. If you’re using sage-woocommerce and still having this problem we’ll be happy to help troubleshoot. First make sure you’re using only one solution at a time, and that you’ve followed the basic instructions included in the readme to get started. Try disabling other plugins and removing any actions or filters you’ve added that affect WooCommerce and see if you can get things working with as few customizations as possible and then start adding things back.

Unfortunately we can’t troubleshoot every project you’ve tried to integrate with, and we recognize that integrating Sage and Woo has been challenging in the past, which is why we recommend this method now and going forward.

If you start a brand new project with sage-woocommerce you will encounter the issue I’m facing.

For the sake of ruling things out, could you show us the content of the template you’re overriding? Maybe there’s a chance something in there could be causing it.

Yeah man, I’ll set up a working example on GitHub next time I’m at the computer.

I have a demo theme set up at:

If you already have sage-woocommerce set up in a demo theme, you can just add the template instead:


Display single product reviews (comments)

This template can be overridden by copying it to yourtheme/woocommerce/single-product-reviews.php.

@author 	WooThemes
@package 	WooCommerce/Templates
@version  3.2.0

  global $product;

  if ( ! comments_open() ) {

<div id="reviews" class="woocommerce-Reviews">
	<div id="comments">
    {{-- NOTE: the following line has been changed, note how it doesn't show --}}
		<h2 class="woocommerce-Reviews-title">This should be showing</h2>

		@if ( have_comments() )

			<ol class="commentlist">
				@php wp_list_comments( apply_filters( 'woocommerce_product_review_list_args', array( 'callback' => 'woocommerce_comments' ) ) ); @endphp

        if ( get_comment_pages_count() > 1 && get_option( 'page_comments' ) ) {
          echo '<nav class="woocommerce-pagination">';
          paginate_comments_links( apply_filters( 'woocommerce_comment_pagination_args', array(
            'prev_text' => '&larr;',
            'next_text' => '&rarr;',
            'type'      => 'list',
          ) ) );
          echo '</nav>';


			<p class="woocommerce-noreviews">@php _e( 'There are no reviews yet.', 'woocommerce' ); @endphp</p>


	@if ( get_option( 'woocommerce_review_rating_verification_required' ) === 'no' || wc_customer_bought_product( '', get_current_user_id(), $product->get_id() ) )

		<div id="review_form_wrapper">
			<div id="review_form">
					$commenter = wp_get_current_commenter();

					$comment_form = array(
						'title_reply'          => have_comments() ? __( 'Add a review', 'woocommerce' ) : sprintf( __( 'Be the first to review &ldquo;%s&rdquo;', 'woocommerce' ), get_the_title() ),
						'title_reply_to'       => __( 'Leave a Reply to %s', 'woocommerce' ),
						'title_reply_before'   => '<span id="reply-title" class="comment-reply-title">',
						'title_reply_after'    => '</span>',
						'comment_notes_after'  => '',
						'fields'               => array(
							'author' => '<p class="comment-form-author">' . '<label for="author">' . esc_html__( 'Name', 'woocommerce' ) . '&nbsp;<span class="required">*</span></label> ' .
										'<input id="author" name="author" type="text" value="' . esc_attr( $commenter['comment_author'] ) . '" size="30" aria-required="true" required /></p>',
							'email'  => '<p class="comment-form-email"><label for="email">' . esc_html__( 'Email', 'woocommerce' ) . '&nbsp;<span class="required">*</span></label> ' .
										'<input id="email" name="email" type="email" value="' . esc_attr( $commenter['comment_author_email'] ) . '" size="30" aria-required="true" required /></p>',
						'label_submit'  => __( 'Submit', 'woocommerce' ),
						'logged_in_as'  => '',
						'comment_field' => '',

					if ( $account_page_url = wc_get_page_permalink( 'myaccount' ) ) {
						$comment_form['must_log_in'] = '<p class="must-log-in">' . sprintf( __( 'You must be <a href="%s">logged in</a> to post a review.', 'woocommerce' ), esc_url( $account_page_url ) ) . '</p>';

					if ( get_option( 'woocommerce_enable_review_rating' ) === 'yes' ) {
						$comment_form['comment_field'] = '<div class="comment-form-rating"><label for="rating">' . esc_html__( 'Your rating', 'woocommerce' ) . '</label><select name="rating" id="rating" aria-required="true" required>
							<option value="">' . esc_html__( 'Rate&hellip;', 'woocommerce' ) . '</option>
							<option value="5">' . esc_html__( 'Perfect', 'woocommerce' ) . '</option>
							<option value="4">' . esc_html__( 'Good', 'woocommerce' ) . '</option>
							<option value="3">' . esc_html__( 'Average', 'woocommerce' ) . '</option>
							<option value="2">' . esc_html__( 'Not that bad', 'woocommerce' ) . '</option>
							<option value="1">' . esc_html__( 'Very poor', 'woocommerce' ) . '</option>

					$comment_form['comment_field'] .= '<p class="comment-form-comment"><label for="comment">' . esc_html__( 'Your review', 'woocommerce' ) . '&nbsp;<span class="required">*</span></label><textarea id="comment" name="comment" cols="45" rows="8" aria-required="true" required></textarea></p>';

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


		<p class="woocommerce-verification-required">@php _e( 'Only logged in customers who have purchased this product may leave a review.', 'woocommerce' ); @endphp</p>


	<div class="clear"></div>

You’ll notice that none of the changes you make actually show through… I believe this is because the template is loaded differently than others (see above) but I can’t figure out a way around it. This issue only happens with sage themes.

WooCommerce loads this template partial differently, using the comments_template filter instead of the template_include filter. We’ve filtered the latter in roots/sage-woocommerce, but not the former (yet). I’m assuming sage-woo is in the same boat, but haven’t checked it.

Here are the relevant bits from WooCommerce:


Method hooked onto the filter:

I’ve submitted a PR to roots/sage-woocommerce to fix this. You may be able to adapt it for sage-woo. See

Edit: This PR has been released in Sage WooCommerce 1.0.3.


It works beautifully, thanks @mmirus!

1 Like