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

Table::render_contentprotectedWC 1.0

Renders the block content.

Method of the class: Table{}

No Hooks.

Returns

String.

Usage

// protected - for code of main (parent) or child class
$result = $this->render_content( $block_content, $parsed_block, $rendering_context ): string;
$block_content(string) (required)
Block content.
$parsed_block(array) (required)
Parsed block.
$rendering_context(Rendering_Context) (required)
Rendering context.

Table::render_content() code WC 10.5.0

protected function render_content( string $block_content, array $parsed_block, Rendering_Context $rendering_context ): string {
	// Extract table content and caption from figure wrapper if present.
	$extracted_data = $this->extract_table_and_caption_from_figure( $block_content );
	$table_content  = $extracted_data['table'];
	$caption        = $extracted_data['caption'];

	// Validate that we have actual table content.
	if ( ! $this->is_valid_table_content( $table_content ) ) {
		return '';
	}

	// Check for empty table structures - tables with no th or td elements.
	if ( ! preg_match( '/<(th|td)/i', $table_content ) ) {
		return '';
	}

	$block_attributes = wp_parse_args(
		$parsed_block['attrs'] ?? array(),
		array(
			'textAlign' => 'left',
			'style'     => array(),
		)
	);

	$html    = new \WP_HTML_Tag_Processor( $table_content );
	$classes = 'email-table-block';

	if ( $html->next_tag() ) {
		$block_classes = (string) ( $html->get_attribute( 'class' ) ?? '' );
		$classes      .= ' ' . $block_classes;
		// Clean classes for table element.
		$block_classes = Html_Processing_Helper::clean_css_classes( $block_classes );
		$html->set_attribute( 'class', $block_classes );
		$table_content = $html->get_updated_html();
	}

	// Clean wrapper classes.
	$classes = Html_Processing_Helper::clean_css_classes( $classes );

	// Get spacing styles for wrapper and table-specific styles separately.
	$spacing_styles = Styles_Helper::get_block_styles( $block_attributes, $rendering_context, array( 'spacing' ) );
	$table_styles   = Styles_Helper::get_block_styles( $block_attributes, $rendering_context, array( 'background-color', 'color', 'typography' ) );

	// Ensure background styles are completely removed from spacing styles and force transparent background.
	$spacing_css = $spacing_styles['css'] ?? '';
	$spacing_css = (string) ( preg_replace( '/background[^;]*;?/', '', $spacing_css ) ?? '' );
	$spacing_css = (string) ( preg_replace( '/\s*;\s*;/', ';', $spacing_css ) ?? '' ); // Clean up double semicolons.
	$spacing_css = trim( $spacing_css, '; ' );

	// Force transparent background on wrapper to prevent any background leakage.
	$spacing_styles['css'] = $spacing_css ? $spacing_css . '; background: transparent !important;' : 'background: transparent !important;';

	$additional_styles = array(
		'min-width' => '100%', // Prevent Gmail App from shrinking the table on mobile devices.
	);

	// Add fallback text color when no custom text color or preset text color is set.
	if ( empty( $table_styles['declarations']['color'] ) ) {
		$email_styles = $rendering_context->get_theme_styles();
		$color        = $parsed_block['email_attrs']['color'] ?? $email_styles['color']['text'] ?? '#000000';
		// Sanitize color value to ensure it's a valid hex color.
		$additional_styles['color'] = Html_Processing_Helper::sanitize_color( $color );
	}

	$additional_styles['text-align'] = 'left';
	if ( ! empty( $parsed_block['attrs']['textAlign'] ) ) { // In this case, textAlign needs to be one of 'left', 'center', 'right'.
		$text_align = $parsed_block['attrs']['textAlign'];
		if ( in_array( $text_align, self::VALID_TEXT_ALIGNMENTS, true ) ) {
			$additional_styles['text-align'] = $text_align;
		}
	} elseif ( in_array( $parsed_block['attrs']['align'] ?? null, self::VALID_TEXT_ALIGNMENTS, true ) ) {
		$additional_styles['text-align'] = $parsed_block['attrs']['align'];
	}

	$table_styles = Styles_Helper::extend_block_styles( $table_styles, $additional_styles );

	// Check if this is a striped table style.
	$is_striped_table = $this->is_striped_table( $block_content, $parsed_block );

	// Process the table content to ensure email compatibility BEFORE wrapping.
	$table_content = $this->process_table_content( $table_content, $parsed_block, $rendering_context, $is_striped_table );

	// Apply table-specific styles (background, color, typography) directly to the table element.
	$table_content_with_styles = $this->apply_styles_to_table_element( $table_content, $table_styles['css'] );

	// Add wp-block-table class to the table element for theme.json CSS rules.
	if ( false !== strpos( $block_content, 'wp-block-table' ) ) {
		$table_content_with_styles = $this->add_class_to_table_element( $table_content_with_styles, 'wp-block-table' );
	}

	// Build complete content (table + caption).
	$complete_content = $table_content_with_styles;
	if ( ! empty( $caption ) ) {
		// Use HTML API to safely allow specific tags in caption.
		$sanitized_caption = Html_Processing_Helper::sanitize_caption_html( $caption );
		// Extract typography styles from table styles (not spacing styles) and apply to caption.
		$caption_styles    = $this->extract_typography_styles_for_caption( $table_styles['css'] );
		$complete_content .= '<div style="text-align: center; margin-top: 8px; ' . $caption_styles . '">' . $sanitized_caption . '</div>';
	}

	$table_attrs = array(
		'style' => 'border-collapse: separate;', // Needed because of border radius.
		'width' => '100%',
	);

	// Use spacing styles only for the wrapper.
	$cell_attrs = array(
		'class' => $classes,
		'style' => $spacing_styles['css'],
		'align' => $additional_styles['text-align'],
	);

	$rendered_table = Table_Wrapper_Helper::render_table_wrapper( $complete_content, $table_attrs, $cell_attrs );

	return $rendered_table;
}