Automattic\WooCommerce\Internal\ShopperLists

ShopperListRenderer::render_ssr_common_rowpublic staticWC 1.0

Render the image + title + price triplet for the SSR-mode row, with values populated from $item and $remove_aria_label_template. The binding directives match the template-mode markup so iAPI's hydration is a no-op diff after first paint.

Method of the class: ShopperListRenderer{}

No Hooks.

Returns

String.

Usage

$result = ShopperListRenderer::render_ssr_common_row( $item, $remove_aria_label_template ): string;
$item(array) (required)
.
$remove_aria_label_template(string) (required)
Sprintf template for the remove button's aria-label. %s is replaced with the product name.

ShopperListRenderer::render_ssr_common_row() code WC 10.9.1

<?php
public static function render_ssr_common_row( array $item, string $remove_aria_label_template ): string {
	$is_live         = ! empty( $item['is_live'] );
	$name            = (string) ( $item['name'] ?? '' );
	$permalink       = (string) ( $item['permalink'] ?? '' );
	$alt             = html_entity_decode( $name, ENT_QUOTES, 'UTF-8' );
	$image_html      = (string) ( $item['image_html'] ?? '' );
	$price_html      = (string) ( $item['price_html'] ?? '' );
	$variation_label = self::get_variation_label( $item );
	$remove_aria     = sprintf( $remove_aria_label_template, $alt );
	$is_price_hidden = '' === $price_html;
	// Tombstone rows (`is_live=false` or empty permalink) render `<a>`
	// without an href — keeps the element shape stable for iAPI
	// reconciliation against the live-row template, and the CSS in the
	// shared partial drops link affordances when the anchor has no href.
	$href_attr = $is_live && '' !== $permalink ? 'href="' . esc_url( $permalink ) . '"' : '';

	ob_start();
	?>
	<div class="wc-block-components-product-image wc-block-components-product-image--aspect-ratio-auto">
		<a <?php echo $href_attr; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- pre-escaped above with esc_url(). ?> data-wp-bind--href="context.listItem.permalink">
			<span
				class="<?php echo esc_attr( self::ROW_CLASS ); ?>__image-slot"
				data-wp-context='{"htmlField":"image_html"}'
				data-wp-watch="callbacks.updateInnerHtml"
			>
				<?php echo wp_kses_post( $image_html ); ?>
			</span>
		</a>
		<button
			type="button"
			class="<?php echo esc_attr( self::ROW_CLASS ); ?>__remove"
			aria-label="<?php echo esc_attr( $remove_aria ); ?>"
			data-wp-on--click="actions.onClickRemove"
			data-wp-bind--aria-label="state.currentItemRemoveLabel"
			data-wp-bind--disabled="state.isCurrentItemPending"
		>
			<?php echo self::get_remove_icon_svg(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- static SVG markup. ?>
		</button>
		<span
			class="<?php echo esc_attr( self::ROW_CLASS ); ?>__variation"
			data-wp-bind--hidden="!state.currentItemVariationLabel"
			data-wp-text="state.currentItemVariationLabel"
			<?php
			if ( '' === $variation_label ) {
				echo 'hidden';
			}
			?>
		><?php echo esc_html( $variation_label ); ?></span>
	</div>
	<h2 class="wp-block-post-title has-text-align-center has-medium-font-size">
		<a <?php echo $href_attr; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- pre-escaped above with esc_url(). ?> data-wp-bind--href="context.listItem.permalink" data-wp-text="state.currentItemDisplayName"><?php echo esc_html( $alt ); ?></a>
	</h2>
	<div
		class="price wc-block-components-product-price has-text-align-center has-small-font-size"
		data-wp-bind--hidden="state.isPriceHidden"
		data-wp-context='{"htmlField":"price_html"}'
		data-wp-watch="callbacks.updateInnerHtml"
		<?php
		if ( $is_price_hidden ) {
			echo 'hidden';
		}
		?>
	>
		<?php echo wp_kses_post( $price_html ); ?>
	</div>
	<?php
	return (string) ob_get_clean();
}