Product review error in Google structure data analyzer when using X6.0.4

Getting back to an error I reported earlier on Google Structured data errors (https://theme.co/apex/forum/t/two-errors-with-product-and-review-structured-data-after-update-to-x6-0-1-wc3-2-6/25331/4)
The translation error was due to Woocommerce but the error reported for reviews seems to be caused by X.

Here are some screenshot to show the situation. This is the error reported by the Google structured data tester for Reviews when X theme is active:


The same product when standard WP theme used:

This is the html code when a standard theme is used:

And here is the code when X is used and the error is reported. So clearly the code that Google complains about is genereated by X (as seen from the classes etc etc)

It would be good if X left the structured data alone and used the output from WC. This now is the last error stopping me from going live with X6 so I hope this could be fixed.

Hi there,

Thanks for writing in.

Please add this code to your child theme’s functions.php

  function x_renew_comment( $comment, $args, $depth ) {

    $GLOBALS['comment'] = $comment;
    switch ( $comment->comment_type ) :
      case 'pingback' :  // 1
      case 'trackback' : // 1
    ?>
    <li <?php comment_class(); ?> id="comment-<?php comment_ID(); ?>">
      <p><?php _e( 'Pingback:', '__x__' ); ?> <?php comment_author_link(); ?> <?php edit_comment_link( __( '(Edit)', '__x__' ), '<span class="edit-link">', '</span>' ); ?></p>
    <?php
        break;
      default : // 2
      GLOBAL $post;
      if ( X_WOOCOMMERCE_IS_ACTIVE ) :
        $rating = esc_attr( get_comment_meta( $GLOBALS['comment']->comment_ID, 'rating', true ) );
      endif;
      if ( x_is_product() ) {
        $comment_avatar = get_avatar( $comment, 240 );
      } else {
        $comment_avatar = get_avatar( $comment, 120 );
      }
    ?>
    <li id="li-comment-<?php comment_ID(); ?>" itemprop="review" itemscope itemtype="http://schema.org/Review" <?php comment_class(); ?>>
      <article id="comment-<?php comment_ID(); ?>" class="comment">
        <?php
        printf( '<div class="x-comment-img">%s</div>',
          '<span class="avatar-wrap cf">' . $comment_avatar . '</span>'
        );
        ?>
        <?php if ( ! x_is_product() ) : ?>
        <div class="x-reply">
          <?php comment_reply_link( array_merge( $args, array( 'reply_text' => __( 'Reply <span class="comment-reply-link-after"><i class="x-icon-reply" data-x-icon="&#xf112;"></i></span>', '__x__' ), 'depth' => $depth, 'max_depth' => $args['max_depth'] ) ) ); ?>
        </div>
        <?php endif; ?>
        <div class="x-comment-wrap">
          <header class="x-comment-header">
            <?php
            printf( '<cite class="x-comment-author" itemprop="author">%1$s</cite>',
              get_comment_author_link()
            );
            if ( x_is_product() && get_option('woocommerce_enable_review_rating') == 'yes' ) : ?>
              <div class="star-rating-container">
                <div itemprop="reviewRating" itemscope itemtype="http://schema.org/Rating" class="star-rating" title="<?php echo sprintf( __( 'Rated %d out of 5', '__x__' ), $rating ) ?>">
                  <span style="width:<?php echo ( intval( get_comment_meta( $GLOBALS['comment']->comment_ID, 'rating', true ) ) / 5 ) * 100; ?>%"><strong itemprop="ratingValue"><?php echo intval( get_comment_meta( $GLOBALS['comment']->comment_ID, 'rating', true ) ); ?></strong> <?php _e( 'out of 5', '__x__' ); ?></span>
                  <div itemprop="itemReviewed" itemscope itemtype="http://schema.org/Product">
                </div>
              </div>
            <?php endif;
            printf( '<div><a href="%1$s" class="x-comment-time"><time itemprop="datePublished" datetime="%2$s">%3$s</time></a></div>',
              esc_url( get_comment_link( $comment->comment_ID ) ),
              get_comment_time( 'c' ),
              sprintf( __( '%1$s at %2$s', '__x__' ),
                get_comment_date( 'm.d.Y' ),
                get_comment_time()
              )
            );
            edit_comment_link( __( '<i class="x-icon-edit" data-x-icon="&#xf044;"></i> Edit', '__x__' ) );
            ?>
          </header>
          <?php if ( '0' == $comment->comment_approved ) : ?>
            <p class="x-comment-awaiting-moderation"><?php _e( 'Your comment is awaiting moderation.', '__x__' ); ?></p>
          <?php endif; ?>
          <section class="x-comment-content" itemprop="description">
            <?php comment_text(); ?>
          </section>
        </div>
      </article>
    <?php
        break;
    endswitch;

  }

Then please clear your site’s cache and test it again.

Thanks!

Unfortunately it went from bad to worse…

Just wondering why X has to overwrite the WC code/behavior here? There will be an endless race of X to keep up with changes and mods in this space.

Hi there,

What do you mean by WC code? That code is from the theme and not from WC, what I provided is the same code but I just added extra snippet.

<div itemprop="itemReviewed" itemscope itemtype="http://schema.org/Product">

The error means it needs an item for the review, so I added a product schema. Unfortunately, Google doesn’t like it either.

Plus, the one you’re comparing in the screenshot is the comment section (from the theme) and the actual schema (JSON data). And looks like Google is trying to pull information from that comment section since it recognized it as a review section. Would you mind providing your login credentials in a secure note? I’ll check what generates that JSON data and yes, it’s not present on that page.

Thanks!

Just assumed that Review code might be generated by WC? Could be I’m wrong. For access to site, please note.

Hi there,

I compared the two (the latest version and 4.6.4) and the review section’s code is the same.

Where do you get the JSON data from your first screenshot? It’s not part of the review section and maybe that’s what missing.

Thanks!

The test site is a copy of the live. The live site is Woocommerce 2.6.14 + X4.6.4, the test site is X6.0.4 + WC 3.3.4. I’ve made so many errors in assuming who generates the JSON so I won’t guess, but the “x-” classes kind of make me guess it is X? Nothing else (that I know of) touches the structured data for Review or Product on the live site.

If you run both sites thru the Google Structured data test tool, the reviews in the live site are part of “Product” element while in the updated site each review is a separate entity? Here is the analyzer from Google Structured data analyzer for the test site with WC3.3.4 and TwentySixteen.

Hi there,

Yes, class with x- is from X theme but as I said, that area is the same on both latest and 4.6.4. What I’m trying to understand is the JSON data which has no x-. Would you mind providing your site’s admin and FTP login credentials in a secure note? I like to test it myself and please allow me to disable plugins and switch themes.

Thanks!

Sure, please have a look!

Hi there,

I checked and both 4.6.4 and latest version have the same review section, and displayed with same JSON data. But, I went ahead and added the fixes to the above code that I gave. Should be okay now, it’s related to this https://theme.co/apex/forum/t/snippets-extension-problem-the-review-has-no-reviewed-item-specified/6488. But instead of extension, it’s in review section.

Thanks!

Confused now, the site still shows the error so where can I pick up the code fix?
When can we expect an update to X6 that would fix this?

Hey @mrboats,

Sorry for the confusion. I see the issue persists.

I modified @Rad’s code from this:

to this:

The difference is, the previous code was added under the Ratings schema structure and it was also structurally incorrect.

This is the correct code to be added under the Review schema structure.

<div class="visually-hidden" itemprop="itemReviewed" itemscope itemtype="http://schema.org/Thing">
  <span itemprop="name"><?php the_title(); ?></span>
</div>

You can change the itemtype in the code to a type related to your business. See http://schema.org/docs/schemas.html

There are no issues now.

I’ll post this to our issue tracker. We could not give an estimate when the fix would be shipped though.

Regarding the old version of X, the Review schema was not yet introduced in that version that is why there’s no error and the Review Schema is not present in the test. This is also the same in the default WordPress theme where there’s no review schema so there would be no error.

Thanks.

Thanks. Almost there but still one (or two) minor issues. Seems that the “Thing” could (or should) be replaced by Product and Persons respectively. Not causing an error but not sure either if the interpretation will be optimal with “Thing”? The values are good. See attached screen capture for details.

Hi there,

As mentioned by my colleague you need to change the code regarding your need, So in the given code:

<div class="visually-hidden" itemprop="itemReviewed" itemscope itemtype="http://schema.org/Thing">
  <span itemprop="name"><?php the_title(); ?></span>
</div>

Change ttp://schema.org/Thing with the type that you want by checking the link my colleague provided.

Thank you.

OK, I could fix the “Product” in this way. The “Person” seems to be set in the function get_comment_author_link(), is that correct? Is that an X or WC function? Any idea in which file?

OK, so that was a Wordpress function… So seems there should be something like

<div class="visually-hidden" itemprop="itemReviewed" itemscope itemtype="http://schema.org/Person"> <span itemprop="name"><?php get_comment_author_link(); ?></span>

instead of

printf( '<cite class="x-comment-author" itemprop="author">%1$s</cite>', get_comment_author_link() );

but my programming skills are not enough to get it to work… And perhaps the <cite…> is needed for something else?
Still, the “Person” would be nice (?) to also get?

Is there a reason why you do not call this function: ` public function generate_review_data( $comment ) {
$markup = array();
$markup[’@type’] = ‘Review’;
$markup[’@id’] = get_comment_link( $comment->comment_ID );
$markup[‘datePublished’] = get_comment_date( ‘c’, $comment->comment_ID );
$markup[‘description’] = get_comment_text( $comment->comment_ID );
$markup[‘itemReviewed’] = array(
@type’ => ‘Product’,
‘name’ => get_the_title( $comment->comment_post_ID ),
);

	// Skip replies unless they have a rating.
	$rating = get_comment_meta( $comment->comment_ID, 'rating', true );

	if ( $rating ) {
		$markup['reviewRating'] = array(
			'@type'       => 'rating',
			'ratingValue' => $rating,
		);
	} elseif ( $comment->comment_parent ) {
		return;
	}

	$markup['author'] = array(
		'@type' => 'Person',
		'name'  => get_comment_author( $comment->comment_ID ),
	);

	$this->set_data( apply_filters( 'woocommerce_structured_data_review', $markup, $comment ) );
}`

Hello there,

Yes, however please update the code to this instead:

<div class="visually-hidden" itemprop="itemReviewed" itemscope itemtype="http://schema.org/Person">
    <span itemprop="name"><?php get_the_author(); ?></span>
</div>

The function get_comment_author_link() only retrieves the HTML link to the URL of the author, so I advise not to use it.

The code with function generate_review_data() produces meta data from reviews. See this link for more info:

Thank you.

Almost but not quite there yet :frowning:

With

	<div class="visually-hidden" itemprop="author" itemscope itemtype="http://schema.org/Person">
		<span itemprop="name"><?php get_the_author(); ?></span>
	</div>

`

the output misses the actual name:´

<div class="visually-hidden" itemprop="author" itemscope itemtype="http://schema.org/Person"> <span itemprop="name"></span> </div>

I’ve also tried get_comment_author() with and without comment parameter but the name never shows?

Hi there,

Here again, that’s weird. I changed the code and it’s back to <div itemprop="itemReviewed" itemscope itemtype="http://schema.org/Product"> as @christian_y posted. Perhaps you’re editing that time too?

Let’s move to the latest issue, it will not work since the comment section is already outside the query loop. And pulling any post specific data will be empty. Please try this

	<div class="visually-hidden" itemprop="author" itemscope itemtype="http://schema.org/Person">
		<span itemprop="name"><?php echo get_the_author_meta('display_name', get_post_field( 'post_author', get_queried_object_id()  ) ); ?></span>
	</div>

Thanks!