Automattic\WooCommerce\Blocks\BlockTypes

ProductTemplate::renderprotectedWC 1.0

Render the block.

Method of the class: ProductTemplate{}

No Hooks.

Returns

String. | void Rendered block output.

Usage

// protected - for code of main (parent) or child class
$result = $this->render( $attributes, $content, $block );
$attributes(array) (required)
Block attributes.
$content(string) (required)
Block content.
$block(WP_Block) (required)
Block instance.

ProductTemplate::render() code WC 11.0.1

protected function render( $attributes, $content, $block ) {
	$query = ProductCollectionUtils::prepare_and_execute_query( $block );

	if ( ! $query->have_posts() ) {
		return '';
	}

	if ( $this->block_core_post_template_uses_featured_image( $block->inner_blocks ) ) {
		update_post_thumbnail_cache( $query );
	}

	$classnames = '';
	if ( isset( $block->context['displayLayout'] ) && isset( $block->context['query'] ) ) {
		$classnames = 'is-product-collection-layout-' . $block->context['displayLayout']['type'] . ' ';

		if ( isset( $block->context['displayLayout']['type'] ) && 'flex' === $block->context['displayLayout']['type'] ) {
			if ( isset( $block->context['displayLayout']['shrinkColumns'] ) && $block->context['displayLayout']['shrinkColumns'] ) {
				$classnames = "wc-block-product-template__responsive columns-{$block->context['displayLayout']['columns']}";
			} else {
				$classnames = "is-flex-container columns-{$block->context['displayLayout']['columns']}";
			}
		}
	}

	if ( isset( $attributes['style']['elements']['link']['color']['text'] ) ) {
		$classnames .= ' has-link-color';
	}

	$classnames .= ' wc-block-product-template';

	$wrapper_attributes = get_block_wrapper_attributes(
		array(
			'class'              => trim( $classnames ),
			'data-wp-on--scroll' => 'actions.watchScroll',
			'data-wp-init'       => 'callbacks.initResizeObserver',
		)
	);

	$content = '';
	while ( $query->have_posts() ) {
		$query->the_post();

		// Get an instance of the current Post Template block.
		$block_instance = $block->parsed_block;
		$product_id     = (int) get_the_ID();
		$post_type      = get_post_type();

		// Set the block name to one that does not correspond to an existing registered block.
		// This ensures that for the inner instances of the Post Template block, we do not render any block supports.
		$block_instance['blockName'] = 'core/null';

		$filter_block_context = static function ( $context ) use ( $product_id, $post_type ) {
			$context['postType'] = $post_type;
			$context['postId']   = $product_id;
			return $context;
		};

		// Use an early priority so that other 'render_block_context' filters have access to the values.
		add_filter( 'render_block_context', $filter_block_context, 1 );
		// Render the inner blocks of the Post Template block with `dynamic` set to `false` to prevent calling
		// `render_callback` and ensure that no wrapper markup is included.
		$block_content = (
			new WP_Block(
				$block_instance,
				$block->context
			)
		)->render( array( 'dynamic' => false ) );
		remove_filter( 'render_block_context', $filter_block_context, 1 );

		// Load product into the shared products store.
		wc_interactivity_api_load_product(
			'I acknowledge that using experimental APIs means my theme or plugin will inevitably break in the next version of WooCommerce',
			$product_id
		);
		$product_context_directive = wp_interactivity_data_wp_context(
			array(
				'productId'   => $product_id,
				'variationId' => null,
			),
			'woocommerce/products'
		);

		$li_directives = '
			data-wp-interactive="woocommerce/product-collection"
			' . $product_context_directive . '
			data-wp-key="product-item-' . $product_id . '"
		';

		// Wrap the render inner blocks in a `li` element with the appropriate post classes.
		$post_classes = implode( ' ', get_post_class( 'wc-block-product' ) );
		$content     .= strtr(
			'<li class="{classes}"
				{li_directives}
			>
				{content}
			</li>',
			array(
				'{classes}'       => esc_attr( $post_classes ),
				'{li_directives}' => $li_directives,
				'{content}'       => $block_content,
			)
		);
	}

	/*
	* Use this function to restore the context of the template tags
	* from a secondary query loop back to the main query loop.
	* Since we use two custom loops, it's safest to always restore.
	*/
	wp_reset_postdata();

	return sprintf(
		'<ul %1$s>%2$s</ul>',
		$wrapper_attributes,
		$content
	);
}