This shortcode outputs Easy Digital Downloads product/review schema on custom pages, allowing you to show up on Google for Rich Snippets. This is useful if you don’t use the /downloads/ endpoint and have custom product pages.
Usage: `[edd_structured_data id=12345]`
<?php
*
* Example Usage:
* [edd_structured_data id="123"]
*/
add_shortcode(
'edd_structured_data',
function ( $atts ) {
$atts = shortcode_atts( [
'id' => 0,
], $atts );
$download_id = absint( $atts['id'] );
if ( ! $download_id || ! class_exists( 'Easy_Digital_Downloads' ) ) {
return '';
}
$edd = Easy_Digital_Downloads::instance();
$current_post_id = get_the_ID();
// Store the original global post to restore later.
global $post;
$original_post = $post;
// Set the global post to the download post so edd-reviews can find the reviews.
$post = get_post( $download_id );
setup_postdata( $post );
ob_start();
$filter_callback = function ( $data, $download ) use ( $current_post_id ) {
$data['url'] = get_permalink( $current_post_id );
return $data;
};
add_filter( 'edd_generate_download_structured_data', $filter_callback, 10, 2 );
// Generate the schema.
$edd->structured_data->generate_download_data( $download_id );
$edd->structured_data->output_structured_data();
remove_filter( 'edd_generate_download_structured_data', $filter_callback, 10, 2 );
// Restore the original global post.
wp_reset_postdata();
$post = $original_post;
$data = ob_get_clean();
// Remove the last occurrence of aggregateRating from JSON-LD to prevent duplicate AggregateRating warnings.
// Extract JSON from script tag, decode, remove property, and re-encode.
if ( preg_match( '/<script[^>]*type=["']application/ld+json["'][^>]*>(.*?)</script>/s', $data, $json_matches ) ) {
$json_string = $json_matches[1];
$json_data = json_decode( $json_string, true );
if ( is_array( $json_data ) && ! empty( $json_data ) ) {
// Remove aggregateRating from the last item in the array.
$last_index = count( $json_data ) - 1;
if ( isset( $json_data[ $last_index ]['aggregateRating'] ) ) {
unset( $json_data[ $last_index ]['aggregateRating'] );
// Re-encode the JSON and replace in the output.
$new_json = wp_json_encode( $json_data );
$data = str_replace( $json_string, $new_json, $data );
}
}
}
return $data;
}
);