Automattic\WooCommerce\EmailEditor\Integrations\Core\Renderer\Blocks

Post_Content::render_statelesspublicWC 1.0

Stateless render callback for core/post-content block.

This implementation avoids using get_the_content() which relies on global query state, and instead directly accesses post content and applies the_content filter for processing.

Key differences from WordPress's implementation:

  • No static $seen_ids array (allows multiple renders in same request)
  • Uses direct post content access instead of get_the_content()
  • Properly backs up and restores global state

IMPORTANT: This method is only set as the render_callback during email rendering. Outside of email rendering, the original callback is restored, so this method will never be called in non-email contexts.

Method of the class: Post_Content{}

Hooks from the method

Returns

String. Rendered post content HTML.

Usage

$Post_Content = new Post_Content();
$Post_Content->render_stateless( $attributes, $content, $block ): string;
$attributes(array) (required)
Block attributes.
$content(string) (required)
Block content.
$block(WP_Block) (required)
Block instance.

Post_Content::render_stateless() code WC 10.8.1

public function render_stateless( $attributes, $content, $block ): string {
	// This method is only called during email rendering, so we always use stateless logic.
	$post_id = $block->context['postId'] ?? null;

	if ( ! $post_id ) {
		return '';
	}

	$email_post = get_post( $post_id );
	if ( ! $email_post || empty( $email_post->post_content ) ) {
		return '';
	}

	// Backup global state.
	global $post, $wp_query;
	$backup_post  = $post;
	$backup_query = $wp_query;

	// Set up global state for block rendering.
	// This ensures that blocks which depend on global $post work correctly.
	$post = $email_post; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
	// Create a query specifically for this post to ensure proper context.
	$wp_query = new \WP_Query( array( 'p' => $post_id ) ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited

	// Get raw post content and apply the_content filter.
	// The the_content filter processes blocks, shortcodes, etc.
	// We don't use get_the_content() to avoid issues with loop state.
	$post_content = $email_post->post_content;

	// Check for nextpage to display page links for paginated posts.
	if ( has_block( 'core/nextpage', $email_post ) ) {
		$post_content .= wp_link_pages( array( 'echo' => 0 ) );
	}

	// Apply the_content filter to process blocks.
	$post_content = apply_filters( 'the_content', str_replace( ']]>', ']]>', $post_content ) );

	// Restore global state.
	$post     = $backup_post; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
	$wp_query = $backup_query; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited

	if ( empty( $post_content ) ) {
		return '';
	}

	return $post_content;
}