-1

I have a "Product" Google Schema Markup with the pasted loop for the "Reviews". Here's a part of the Markup's code:

     "review": [
            <?php
            $args = array(
            'post_type' => 'my_reviews',
            'category_name' => 'my-product', 
            'paged' => $paged);
    
            $loop = new WP_Query($args);
            if ($loop->have_posts()) :
            while ($loop->have_posts()) : $loop->the_post(); ?>
{
            
            "@type": "Review",
            "reviewRating": {
              "@type": "Rating",
              "ratingValue": "5"
            },
            "author": {
              "@type": "Person",
              "name": "<?php the_title(); ?>"
            },
            "reviewBody": "<?php echo get_the_content(); ?>"},
    <?php
    endwhile;
    endif;
    wp_reset_postdata();
    ?>],
    
          "aggregateRating": {
            "@type": "AggregateRating",
            "ratingValue": "5",
            "bestRating": "5",
            "ratingCount": "<?php echo count_cat_post('My Product'); ?>"
},

Everything works as it should, except that after } of the last object, a comma is still trapped. And it turns out something like the following:

   "review": [{
        "@type": "Review",
        "reviewRating": {
          "@type": "Rating",
          "ratingValue": "5"
        },
        "author": {
          "@type": "Person",
          "name": "John Doe"
        },
        "reviewBody": "Review 1 Content"
      },
      {
        "@type": "Review",
        "reviewRating": {
          "@type": "Rating",
          "ratingValue": "1"
        },
        "author": {
          "@type": "Person",
          "name": "Jane Doe"
        },
        "reviewBody": "Review 2 Content."
      }, <-- this is the comma I need to remove
],
      "aggregateRating": {
        "@type": "AggregateRating",
        "ratingValue": "88",
        "bestRating": "100",
        "ratingCount": "2"
      },

How can I remove it?

Morgari
  • 524
  • 2
  • 8
  • 24
  • If you remove that comma, it makes the JSON invalid! – Dula Nov 25 '21 at 22:41
  • @Dula thank you for your message, but could you, please, look more attentively. The comma I mentioned comes after the figure bracket before the closing square bracket of the array. – Morgari Nov 25 '21 at 22:44
  • Ah..sorry about that! I was not looking closely. But why do you want to remove that comma, as it will not affect anything? – Dula Nov 25 '21 at 22:48
  • I believe you need to count how many entries have you printed and if its the last one just skip the comma: ` "reviewBody": ""}, ` – Toni Michel Caubet Nov 25 '21 at 22:48
  • @ToniMichelCaubet thank you, but it's a dynamic loop and every day I have more and more reviews, so it's impossible to count them. I know the way how to make such a hint with a static markup / reviews, but unfortunately, this way doesn't work with a dynamic loop – Morgari Nov 25 '21 at 22:51
  • @Dula I have to remove it since with this last comma after } and before ] I face the "Structured data with syntax errors detected" markup (Google) error – Morgari Nov 25 '21 at 22:52
  • just something like this `if ($printed < $total) { echo ','; }` else don't print it – Toni Michel Caubet Nov 25 '21 at 22:54
  • @ToniMichelCaubet thank you so much! But could you, please, explain in more detail? I'm afraid my knowledge is not good enough for me to immediately understand what you suggested. – Morgari Nov 25 '21 at 22:55
  • 1
    you can put some condition like this `"reviewBody": ""} current_post + 1 != $loop->post_count) { echo ','; } ?>` – Claymore Nov 25 '21 at 22:58
  • 1
    Yes, @Claymore solution is what I meant, there are better solutions which you should explore when you have the chance ;) – Toni Michel Caubet Nov 26 '21 at 07:21

2 Answers2

1

in wordpress loop you have property current_post for index and post_count for total number of posts. You can use condition ($loop->current_post + 1 != $loop->post_count) to compare that it is not a last post then you can print comma.

so your code for get_the_content should be like this:

"reviewBody": "<?php echo get_the_content(); ?>"} <?php if ($loop->current_post + 1 != $loop->post_count) { echo ','; } ?>

Update for all others : I know json_encode is correct way but he said in comment that he want it like this. But for future viewers, Correct approach should be like this :

// define reviews array
   $reviewArr = [
       'review' => [],
       'aggregateRating' => []
   ];

   // get and loop through posts
    $args = array(
    'post_type' => 'my_reviews',
    'category_name' => 'my-product', 
    'paged' => $paged);

    $loop = new WP_Query($args);
    if ($loop->have_posts()) :
    while ($loop->have_posts()) : $loop->the_post();

        // new post review
        $post_review = [
            
            "@type" => "Review",
            "reviewRating" => [
              "@type" => "Rating",
              "ratingValue" => "5"
            ],
            "author" => [
              "@type" => "Person",
              "name" => "<?php the_title(); ?>"
            ],
            "reviewBody" => get_the_content()
        ];

        // insert the post review in reviews array
        $reviewArr['review'][] = $post_review;

    endwhile;
    endif;
    wp_reset_postdata();

    // aggregate rating
    $aggRating =  [
        "@type" => "AggregateRating",
        "ratingValue" => "5",
        "bestRating" => "5",
        "ratingCount" => count_cat_post('My Product')
    ];

    // insert in reviews array
    $reviewArr['aggregateRating'] = $aggRating;


    //  here you get your json
    $json = json_encode($reviewArr);
Claymore
  • 130
  • 4
  • I must warn all future researchers that this technique MUST NOT be used in professional/stable applications. It is very bad practice to manually craft json strings. PHP natively offers `json_encode()` and that is easily the best way to proceed with this task. You should be gathering all of your data, then when you are done building/manipulating it, encode it. https://stackoverflow.com/questions/38513620/php-foreach-loop-json-encode-issue#comment64424414_38513620 – mickmackusa Nov 26 '21 at 00:27
  • this is NOT the correct way to solve the issue – Ron Nov 26 '21 at 00:51
  • @mickmackus I know json_encode is correct way but he wanted to manually create json data, updated my answer for the json_encode way too. – Claymore Nov 26 '21 at 08:17
0

You hould not be creating JSON by concatenating with a loop, instead within the loop you should be adding your text to an array, and then use implode(',',$yourArray) to convert the array to a JSON, where that last comma would not exist.

Or even better approach is to create nested arrays, and use json_encode() function to create a valid JSON out of a nested array.

Ron
  • 5,900
  • 2
  • 20
  • 30
  • 1
    @Morgari volunteers in Stack Overflow have been saying this same thing for years and years. This answer is giving the correct/professional advice. Don't craft you json strings manually. Please rethink the way that you are coding your application. – mickmackusa Nov 26 '21 at 00:25