ACF\Pro\AI\GEO\Outputs

Blocks::output_block_jsonld_datapublicACF 6.8.0

Output JSON-LD structured data for ACF block fields.

Method of the class: Blocks{}

Returns

null. Nothing (null).

Usage

$Blocks = new Blocks();
$Blocks->output_block_jsonld_data( $block, $content, $is_preview, $post_id, $wp_block, $context );
$block(array) (required)
The block props.
$content(string) (required)
The block content.
$is_preview(true|false) (required)
Whether or not the block is being rendered for editing preview.
$post_id(int) (required)
The current post being edited or viewed.
$wp_block(WP_Block) (required)
The block instance.
$context(array) (required)
The block context array.

Changelog

Since 6.8.0 Introduced.

Blocks::output_block_jsonld_data() code ACF 6.8.8

public function output_block_jsonld_data( $block, $content, $is_preview, $post_id, $wp_block, $context ) {
	/**
	 * Filters whether to output debug comments in HTML
	 *
	 * @since 6.8.0
	 *
	 * @param bool $debug Whether to output debug comments. Default false.
	 */
	$debug = apply_filters( 'acf/schema/debug', false );

	// Don't output JSON-LD in the block editor preview.
	if ( $is_preview ) {
		if ( $debug ) {
			echo "<!-- ACF AI Block JSON-LD: Skipped (block editor preview) -->\n";
		}
		return;
	}

	// Don't output if we don't have a block name.
	if ( empty( $block['name'] ) ) {
		if ( $debug ) {
			echo "<!-- ACF AI Block JSON-LD: Skipped (no block name) -->\n";
		}
		return;
	}

	if ( $debug ) {
		echo '<!-- ACF AI Block JSON-LD: Checking block: ' . esc_html( $block['name'] ) . " -->\n";
	}

	// Get the block type.
	$block_type = acf_get_block_type( $block['name'] );
	if ( ! $block_type ) {
		if ( $debug ) {
			echo '<!-- ACF AI Block JSON-LD: Block type not found for ' . esc_html( $block['name'] ) . " -->\n";
		}
		return;
	}

	// Check if this block has auto_jsonld enabled.
	$auto_jsonld = isset( $block_type['auto_jsonld'] ) ? $block_type['auto_jsonld'] : false;

	/**
	 * Filters whether JSON-LD output is enabled for this specific block.
	 *
	 * @since 6.8.0
	 *
	 * @param boolean $auto_jsonld Whether JSON-LD is enabled for this block.
	 * @param array   $block       The block props.
	 * @param array   $block_type  The block type settings.
	 */
	$auto_jsonld = apply_filters( 'acf/schema/block_jsonld_enabled', $auto_jsonld, $block, $block_type );

	// Exit if auto JSON-LD is not enabled for this block.
	if ( ! $auto_jsonld ) {
		if ( $debug ) {
			echo '<!-- ACF AI Block JSON-LD: Block \'' . esc_html( $block['name'] ) . "' does not have JSON-LD enabled -->\n";
		}
		return;
	}

	/**
	 * Filters the field objects before retrieval, allowing blocks to provide custom data.
	 *
	 * This is useful for blocks that link to other post types or need custom field data handling.
	 * Return a non-null value to short-circuit the default get_field_objects() call.
	 *
	 * @since 6.8.0
	 *
	 * @param array|null $field_objects The field objects array, or null to use default behavior.
	 * @param array      $block         The block props.
	 * @param array      $block_type    The block type settings.
	 * @param int        $post_id       The current post ID.
	 */
	$field_objects = apply_filters( 'acf/schema/block_field_objects', null, $block, $block_type, $post_id );

	/**
	 * Filters the field objects for a specific block name/type.
	 *
	 * The dynamic portion of the hook name, `$block['name']`, refers to the block type name.
	 * For example, 'acf/schema/block_field_objects/block_name=acf/testimonial' for the testimonial block.
	 *
	 * @since 6.8.0
	 *
	 * @param array|null $field_objects The field objects array, or null to use default behavior.
	 * @param array      $block         The block props.
	 * @param array      $block_type    The block type settings.
	 * @param int        $post_id       The current post ID.
	 */
	$field_objects = apply_filters( 'acf/schema/block_field_objects/block_name=' . $block['name'], $field_objects, $block, $block_type, $post_id );

	// If no custom field objects were provided, get them from the block.
	if ( null === $field_objects ) {
		// Get all ACF field objects with values for this block.
		// Use get_field_objects() to get both field metadata and values in a single call.
		$field_objects = get_field_objects( $block['id'], false );
	}

	if ( ! $field_objects || ! is_array( $field_objects ) ) {
		if ( $debug ) {
			echo '<!-- ACF AI Block JSON-LD: No ACF fields found for block ' . esc_html( $block['name'] ) . " -->\n";
		}
		return;
	}

	if ( $debug ) {
		echo '<!-- ACF AI Block JSON-LD: Found ' . count( $field_objects ) . " ACF fields -->\n";
	}

	// Process ACF fields and extract types from qualified properties.
	// This handles schema_property mapping.
	$processed_fields = GEO::process_fields( $field_objects );

	// Get any explicitly set schema type for this block.
	$provided_type = ! empty( $block_type['schema_type'] ) ? $block_type['schema_type'] : null;
	$field_types   = $processed_fields['field_types'] ?? array();

	// Determine the final @type based on provided type or field types from qualified properties.
	// Supports both string (single type) and array (multiple types).
	$schema_type = GEO::determine_schema_type( $provided_type, $field_types, 'PropertyValue' );

	// Remove internal type data from processed fields.
	unset( $processed_fields['field_types'] );

	// Build base JSON-LD structured data.
	$jsonld_data = array(
		'@context' => 'https://schema.org',
		'@type'    => $schema_type, // Can be string or array
		'@id'      => ! empty( $block['id'] ) ? get_permalink( $post_id ) . '#' . $block['id'] : get_permalink( $post_id ),
	);

	// Add block title if available.
	if ( ! empty( $block_type['title'] ) ) {
		$jsonld_data['name'] = $block_type['title'];
	}

	// Add block description if available.
	if ( ! empty( $block_type['description'] ) ) {
		$jsonld_data['description'] = $block_type['description'];
	}

	// Merge processed fields into JSON-LD data.
	$jsonld_data = array_merge( $jsonld_data, $processed_fields );

	/**
	 * Filters the JSON-LD data before output for a block.
	 *
	 * @since 6.8.0
	 *
	 * @param array $jsonld_data The JSON-LD data array.
	 * @param array $block       The block props.
	 * @param array $block_type  The block type settings.
	 */
	$jsonld_data = apply_filters( 'acf/schema/data', $jsonld_data, $block, $block_type );

	// Only output if we have data after filtering.
	if ( empty( $jsonld_data ) ) {
		return;
	}

	// Output the JSON-LD using the shared helper.
	GEO::render_jsonld_script( $jsonld_data );
}