questions

Schema markup from a PHP loop

Rate this post

I am trying to auto generate a schema markup from a WordPress PHP loop. I am trying to create my markup from five latest post in my “hovedret” WordPress post category.

The schema markup I am trying to generate:

<script type="application/ld+json">
    {
      "@context":"https://schema.org",
      "@type":"ItemList",
      "itemListElement":[
        {
          "@type":"ListItem",
          "position":1,
          "url":"http://example.com/peanut-butter-cookies.html"
        },
        {
          "@type":"ListItem",
          "position":2,
          "url":"http://example.com/triple-chocolate-chunk.html"
        },
        {
          "@type":"ListItem",
          "position":3,
          "url":"http://example.com/snickerdoodles.html"
        }
      ]
    }
    </script>

My code should loop through the latest five posts in “hovedret” category so I would have positions 1, 2, 3, 4, and 5. I am using get_the_permalink in order to fill in URL.

I am using wp_head hook in order to return my code in of my website. For some reason, the code breaks my site. I am not sure if I have constructed my while loop the right way or something else is wrong with my code? I have tried echo instead of return $string;

any clues on what I am missing ??

//SCHEMA MARKUP
function tt_hook_schema_new()
{
  if ( is_category() ) 
  {
        $post_per_page = 5;
            $the_query = new WP_Query( array( 'category_name' => 'hovedret', 'posts_per_page' => $post_per_page ) ); 
            
      if ( $the_query->have_posts() ) 
      {
                    $string .= '<script type="application/ld+json">
                                        {
                                    "@context":"https://schema.org",
                                    "@type":"ItemList",
                      "itemListElement":[';
          $counter = 0;
          
          while ( $the_query->have_posts() )
          {
              $counter = $counter + 1;
              $string .= '{';
              $string .= '"@type":"ListItem",';
              $string .= '"position":' . $counter;
              $string .= '"url":"' . get_the_permalink() . '"';   
              $string .= '}';
              
              if($counter != $post_per_page)
              {
                $string .= ',';
              }
          }
          $string .= ']
                                }
                      </script>';
                      
        return $string;

/* Restore original Post Data */
wp_reset_postdata();
            }

  }
}
add_action('wp_head', 'tt_hook_schema_new');

 

✔️Solution:

There is one syntax error:

$string .= '<script type="application/ld+json"> should become
$string = '<script type="application/ld+json">
(removing the dot, since $string wasn’t defined before).

And you run into an infinite loop, since you never get the next post. It should be:

while ( $the_query->have_posts() ) {
    $the_query->the_post();
    // ...
}

And you still have to echo the contents.

Edit: I fixed some more mistakes and here is a corrected version (look at the comments for the changes):

function tt_hook_schema_new() {
    if ( is_category() ) {
        $post_per_page = 5;
        $the_query     = new WP_Query(
            array(
                'category_name'  => 'hovedret',
                'posts_per_page' => $post_per_page,
            )
        );

        if ( $the_query->have_posts() ) {
            // Here was a `.` too much.
            $string  = '<script type="application/ld+json">
                        {
                            "@context":"https://schema.org",
                            "@type":"ItemList",
                            "itemListElement":[';
            $counter = 0;

            while ( $the_query->have_posts() ) {
                // This line was missing.
                $the_query->the_post();

                $counter++;
                $string .= '{';
                $string .= '"@type":"ListItem",';
                // There was a missing comma.
                $string .= '"position":' . $counter . ',';
                $string .= '"url":"' . get_the_permalink() . '"';
                $string .= '}';

                // Having less then `$post_per_page` would still have the last comma.
                if ( $counter < $the_query->found_posts ) {
                    $string .= ',';
                }
            }
            $string .= ']
                    }
                    </script>';

            // Echoing stuff without escaping can be insecure!
            echo $string;
        }
        // You should reset postdata outside the `if` statement.
        /* Restore original Post Data */
        wp_reset_postdata();
    }
}
add_action( 'wp_head', 'tt_hook_schema_new' );

Leave a Reply

Your email address will not be published.

Back to top button