Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
Product Collection: Use Interactivity API for pagination (#10361)
Browse files Browse the repository at this point in the history
* Update router to hydrate only interactive regions

* Rename link directive to navigation-link

* Add navigation directives to Query and Pagination blocks

* Enable the Interactivity API by default

* Remove client-side navigation meta tag

* Cache initial regions

* Move data-wc-interactive from query to query-pagination

* Add woo prefix to navigation id

* Add keys and move wc-interactive back to the query block

* Reuse root fragments for each interactive region

* Fix navigation-id retrieval

* Introduce interactivity to Product Collection block and navigation enhancements

This commit brings significant improvements to the ProductCollection block.

1. A new property `parsed_block` is added to the class to hold the block with its attributes before it gets rendered. This allows for more complex manipulations of the block and its attributes.

2. Interactivity has been added to the product collection block. The block is marked as an interactive region so it can be updated during client-side navigation. The `add_navigation_id_directive` method is responsible for adding this functionality. This ensures better UX as users navigate through the products.

3. Navigation links inside the Query Pagination block are also made interactive. The `add_navigation_link_directives` function is responsible for this. All anchor tags in the pagination are given the `data-wc-navigation-link` attribute with relevant navigation payload. This includes prefetching and scroll behavior. The pagination links are given unique keys for 'previous' and 'next' navigation.

4. The `render_block` filter hook has been used to add these functionalities to the product collection and query pagination blocks during render.

* Disable scroll

---------

Co-authored-by: David Arenas <david.arenas@automattic.com>
  • Loading branch information
imanish003 and DAreRodz authored Aug 11, 2023
1 parent 64ea19b commit 7df7e87
Showing 1 changed file with 90 additions and 0 deletions.
90 changes: 90 additions & 0 deletions src/BlockTypes/ProductCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ class ProductCollection extends AbstractBlock {
*/
protected $block_name = 'product-collection';

/**
* The Block with its attributes before it gets rendered
*
* @var array
*/
protected $parsed_block;

/**
* All query args from WP_Query.
*
Expand Down Expand Up @@ -84,6 +91,87 @@ protected function initialize() {

// Extend allowed `collection_params` for the REST API.
add_filter( 'rest_product_collection_params', array( $this, 'extend_rest_query_allowed_params' ), 10, 1 );

// Interactivity API: Add navigation directives to the product collection block.
add_filter( 'render_block_woocommerce/product-collection', array( $this, 'add_navigation_id_directive' ), 10, 3 );
add_filter( 'render_block_core/query-pagination', array( $this, 'add_navigation_link_directives' ), 10, 3 );
}

/**
* Mark the Product Collection as an interactive region so it can be updated
* during client-side navigation.
*
* @param string $block_content The block content.
* @param array $block The full block, including name and attributes.
* @param \WP_Block $instance The block instance.
*/
public function add_navigation_id_directive( $block_content, $block, $instance ) {
$is_product_collection_block = $block['attrs']['query']['isProductCollectionBlock'] ?? false;
if ( $is_product_collection_block ) {
// Enqueue the Interactivity API runtime.
wp_enqueue_script( 'wc-interactivity' );

$p = new \WP_HTML_Tag_Processor( $block_content );

// Add `data-wc-navigation-id to the query block.
if ( $p->next_tag( array( 'class_name' => 'wp-block-woocommerce-product-collection' ) ) ) {
$p->set_attribute(
'data-wc-navigation-id',
'wc-product-collection-' . $this->parsed_block['attrs']['queryId']
);
$p->set_attribute( 'data-wc-interactive', true );
$block_content = $p->get_updated_html();
}
}

return $block_content;
}

/**
* Add interactive links to all anchors inside the Query Pagination block.
*
* @param string $block_content The block content.
* @param array $block The full block, including name and attributes.
* @param \WP_Block $instance The block instance.
*/
public function add_navigation_link_directives( $block_content, $block, $instance ) {
$is_product_collection_block = $instance->context['query']['isProductCollectionBlock'] ?? false;

if (
$is_product_collection_block &&
$instance->context['queryId'] === $this->parsed_block['attrs']['queryId']
) {
$p = new \WP_HTML_Tag_Processor( $block_content );
$p->next_tag( array( 'class_name' => 'wp-block-query-pagination' ) );

while ( $p->next_tag( 'a' ) ) {
$class_attr = $p->get_attribute( 'class' );
$class_list = preg_split( '/\s+/', $class_attr );

$is_previous = in_array( 'wp-block-query-pagination-previous', $class_list, true );
$is_next = in_array( 'wp-block-query-pagination-next', $class_list, true );
$is_previous_or_next = $is_previous || $is_next;

$navigation_link_payload = array(
'prefetch' => $is_previous_or_next,
'scroll' => false,
);

$p->set_attribute(
'data-wc-navigation-link',
wp_json_encode( $navigation_link_payload )
);

if ( $is_previous ) {
$p->set_attribute( 'key', 'pagination-previous' );
} elseif ( $is_next ) {
$p->set_attribute( 'key', 'pagination-next' );
}
}
$block_content = $p->get_updated_html();
}

return $block_content;
}

/**
Expand Down Expand Up @@ -150,6 +238,8 @@ public function add_support_for_filter_blocks( $pre_render, $parsed_block ) {
return;
}

$this->parsed_block = $parsed_block;

$this->asset_data_registry->add( 'hasFilterableProducts', true, true );
/**
* It enables the page to refresh when a filter is applied, ensuring that the product collection block,
Expand Down

0 comments on commit 7df7e87

Please sign in to comment.