Automattic\WooCommerce\Internal\ShopperLists
ShopperListRenderer::render_ssr_common_row
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.
%sis replaced with the product name.
ShopperListRenderer::render_ssr_common_row() 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();
}