Automattic\WooCommerce\Blocks\BlockTypes
ProductFilterChips{} │ final │ WC 1.0└─ AbstractBlock
Product Filter: Chips Block.
No Hooks.
Usage
$ProductFilterChips = new ProductFilterChips(); // use class methods
Methods
- protected enqueue_data( array $attributes = array() )
- private get_item_swatch_style( array $item )
- private static has_visual_swatches( array $items )
- protected render( $attributes, $content, $block )
ProductFilterChips{} ProductFilterChips{} code WC 10.9.4
<?php
final class ProductFilterChips extends AbstractBlock {
use EnableBlockJsonAssetsTrait;
/**
* Block name.
*
* @var string
*/
protected $block_name = 'product-filter-chips';
/**
* Extra data passed through from server to client for block.
*
* @param array $attributes Any attributes that currently are available from the block.
* Note, this will be empty in the editor context when the block is
* not in the post content on editor load.
* @return void
*/
protected function enqueue_data( array $attributes = array() ) {
parent::enqueue_data( $attributes );
if ( is_admin() ) {
$this->asset_data_registry->add( 'globalStylesColors', wp_get_global_styles( array( 'color' ) ) );
}
}
/**
* Render the block.
*
* @param array $attributes Block attributes.
* @param string $content Block content.
* @param \WP_Block $block Block instance.
* @return string Rendered block type output.
*/
protected function render( $attributes, $content, $block ) {
if ( empty( $block->context['woocommerce/selectableItems'] ) ) {
return '';
}
$block_context = $block->context['woocommerce/selectableItems'];
$items = is_array( $block_context['items'] ?? null ) ? $block_context['items'] : array();
$store_namespace = $block_context['storeNamespace'] ?? 'woocommerce/product-filters';
$display_limit = 'woocommerce/product-filters' === $store_namespace ? 15 : 30;
$classes = '';
$style = '';
$tags = new \WP_HTML_Tag_Processor( $content );
if ( $tags->next_tag( array( 'class_name' => 'wc-block-product-filter-chips' ) ) ) {
$classes = $tags->get_attribute( 'class' );
$style = $tags->get_attribute( 'style' );
}
$wrapper_attributes = array(
'data-wp-interactive' => 'woocommerce/product-filter-chips',
'data-wp-init--colors' => 'callbacks.initColors',
'data-wp-context' => (string) wp_json_encode(
array(
'storeNamespace' => $store_namespace,
'displayLimit' => $display_limit,
'isExpanded' => false,
),
JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP
),
'class' => esc_attr( $classes ),
);
if ( ! empty( $style ) ) {
// Styles generated by Supports API doesn't include semicolon at the end.
$wrapper_attributes['style'] = esc_attr( $style ) . ';';
}
$attribute_id = $block->context['woocommerce/attributeId'] ?? '';
$has_external_label = is_string( $attribute_id ) && '' !== $attribute_id;
if ( $has_external_label ) {
$wrapper_attributes['role'] = 'single' === $block_context['selectionMode'] ? 'radiogroup' : 'group';
$wrapper_attributes['aria-labelledby'] = esc_attr( $attribute_id . '_label' );
}
$first_items = array_slice( $items, 0, $display_limit, true );
$overflow_items = array_slice( $items, $display_limit );
$overflow_selected_items = array_filter( $overflow_items, fn( $item ) => is_array( $item ) && ! empty( $item['selected'] ) );
$visible_items = array_merge( $first_items, $overflow_selected_items );
$hidden_count = count( $items ) - count( $visible_items );
$first_item = reset( $items );
$show_counts = is_array( $first_item ) && array_key_exists( 'count', $first_item );
$has_visual_swatches = self::has_visual_swatches( $items );
$button_role = 'single' === $block_context['selectionMode'] ? 'radio' : 'checkbox';
if ( $has_visual_swatches && is_string( $classes ) && ! str_contains( $classes, 'is-style-swatch' ) ) {
$classes .= ' is-style-swatch';
$wrapper_attributes['class'] = esc_attr( $classes );
}
ob_start();
?>
<div <?php echo get_block_wrapper_attributes( $wrapper_attributes ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
<fieldset class="wc-block-product-filter-chips__fieldset">
<?php if ( ! empty( $block_context['groupLabel'] ) && ! $has_external_label ) : ?>
<legend class="screen-reader-text"><?php echo esc_html( $block_context['groupLabel'] ); ?></legend>
<?php endif; ?>
<div class="wc-block-product-filter-chips__items">
<?php
foreach ( $visible_items as $item ) :
?>
<button
class="wc-block-product-filter-chips__item"
type="button"
role="<?php echo esc_attr( $button_role ); ?>"
id="<?php echo esc_attr( $item['id'] ); ?>"
<?php if ( ! empty( $item['ariaLabel'] ) ) : ?>
aria-label="<?php echo esc_attr( $item['ariaLabel'] ); ?>"
<?php endif; ?>
<?php if ( $has_visual_swatches ) : ?>
title="<?php echo esc_attr( $item['label'] ); ?>"
<?php endif; ?>
value="<?php echo esc_attr( $item['value'] ); ?>"
aria-checked="<?php echo ! empty( $item['selected'] ) ? 'true' : 'false'; ?>"
<?php disabled( ! empty( $item['disabled'] ) ); ?>
data-wp-each-child
<?php echo wp_interactivity_data_wp_context( array( 'item' => $item ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
data-wp-bind--aria-checked="context.item.selected"
data-wp-bind--disabled="context.item.disabled"
data-wp-bind--hidden="context.item.hidden"
data-wp-on--click="actions.toggle"
>
<span class="wc-block-product-filter-chips__label">
<?php if ( $has_visual_swatches ) : ?>
<?php
$swatch_style = $this->get_item_swatch_style( $item );
$has_visual = '' !== $swatch_style;
?>
<span
class="wc-block-product-filter-chips__swatch<?php echo ! $has_visual ? ' wc-block-product-filter-chips__swatch--no-color' : ''; ?>"
<?php if ( $has_visual ) : ?>
style="<?php echo esc_attr( $swatch_style ); ?>"
<?php endif; ?>
aria-hidden="true"
></span>
<?php endif; ?>
<span class="wc-block-product-filter-chips__text">
<?php echo esc_html( $item['label'] ); ?>
</span>
<?php if ( isset( $item['count'] ) ) : ?>
<span class="wc-block-product-filter-chips__count">
(<span data-wp-text="context.item.count"><?php echo esc_html( $item['count'] ); ?></span>)
</span>
<?php endif; ?>
</span>
</button>
<?php endforeach; ?>
<template
data-wp-each--item="state.items"
data-wp-each-key="context.item.id"
>
<button
class="wc-block-product-filter-chips__item"
type="button"
role="<?php echo esc_attr( $button_role ); ?>"
data-wp-bind--id="context.item.id"
data-wp-bind--aria-label="context.item.ariaLabel"
<?php if ( $has_visual_swatches ) : ?>
data-wp-bind--title="context.item.label"
<?php endif; ?>
data-wp-bind--value="context.item.value"
data-wp-bind--aria-checked="context.item.selected"
data-wp-bind--disabled="context.item.disabled"
data-wp-bind--hidden="context.item.hidden"
data-wp-on--click="actions.toggle"
>
<span class="wc-block-product-filter-chips__label">
<?php if ( $has_visual_swatches ) : ?>
<span
class="wc-block-product-filter-chips__swatch"
data-wp-class--wc-block-product-filter-chips__swatch--no-color="woocommerce/product-filter-chips::state.swatchHidden"
data-wp-bind--style="woocommerce/product-filter-chips::state.swatchStyle"
aria-hidden="true"
></span>
<?php endif; ?>
<span
class="wc-block-product-filter-chips__text"
data-wp-text="context.item.label"
></span>
<?php if ( $show_counts ) : ?>
<span class="wc-block-product-filter-chips__count">
(<span data-wp-text="context.item.count"></span>)
</span>
<?php endif; ?>
</span>
</button>
</template>
</div>
<?php if ( $hidden_count > 0 ) : ?>
<button
type="button"
class="wc-block-product-filter-chips__show-more"
data-wp-on--click="actions.showAll"
data-wp-bind--hidden="context.isExpanded"
>
<?php
/* translators: %d: number of hidden items */
echo esc_html( sprintf( __( '+%d more', 'woocommerce' ), $hidden_count ) );
?>
</button>
<?php endif; ?>
</fieldset>
</div>
<?php
return ob_get_clean();
}
/**
* Check whether any item has visual swatch data.
*
* @param array $items Selectable items.
* @return bool
*/
private static function has_visual_swatches( array $items ): bool {
foreach ( $items as $item ) {
if ( is_array( $item ) && array_key_exists( 'visual', $item ) ) {
return true;
}
}
return false;
}
/**
* Build inline swatch style from item visual data.
*
* @param array $item Selectable item data.
* @return string
*/
private function get_item_swatch_style( array $item ): string {
$visual = isset( $item['visual'] ) && is_array( $item['visual'] ) ? $item['visual'] : array();
return VisualAttributeTermMeta::get_swatch_style( $visual );
}
}