From 67feb8ce94af09273c9b72123fb3615e01caead9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Wed, 27 Oct 2021 15:36:13 +0200 Subject: [PATCH 01/21] Fix wrong event prefix in doc comment --- assets/js/base/utils/render-frontend.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/base/utils/render-frontend.js b/assets/js/base/utils/render-frontend.js index 1e75c68262f..dc5e3dc1a38 100644 --- a/assets/js/base/utils/render-frontend.js +++ b/assets/js/base/utils/render-frontend.js @@ -141,7 +141,7 @@ const renderBlockInsideWrapper = ( { * Renders the block frontend on page load. If the block is contained inside a * wrapper element that should be excluded from initial load, it adds the * appropriate event listeners to render the block when the - * `blocks_render_blocks_frontend` event is triggered. + * `wc-blocks_render_blocks_frontend` event is triggered. * * @param {Object} props Render props. * @param {Function} props.Block React component to use as a From 87d711e6ed5c01427362b0fce49f6c44b53ed7bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Wed, 27 Oct 2021 15:37:22 +0200 Subject: [PATCH 02/21] Make className prop in CartLineItemsTableProps optional --- .../blocks/cart-checkout/cart/cart-line-items-table/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/blocks/cart-checkout/cart/cart-line-items-table/index.tsx b/assets/js/blocks/cart-checkout/cart/cart-line-items-table/index.tsx index 986d36c3748..e9a22366255 100644 --- a/assets/js/blocks/cart-checkout/cart/cart-line-items-table/index.tsx +++ b/assets/js/blocks/cart-checkout/cart/cart-line-items-table/index.tsx @@ -19,7 +19,7 @@ const placeholderRows = [ ...Array( 3 ) ].map( ( _x, i ) => ( interface CartLineItemsTableProps { lineItems: CartResponseItem[]; isLoading: boolean; - className: string; + className?: string; } const setRefs = ( lineItems: CartResponseItem[] ) => { From 414bed1abb96434a9f63a952f8ffa820ac44c939 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Thu, 28 Oct 2021 09:47:30 +0200 Subject: [PATCH 03/21] Mini Cart as template part --- .../mini-cart-contents/block.tsx | 104 +++++++++++ .../cart-checkout/mini-cart-contents/edit.tsx | 17 ++ .../mini-cart-contents/index.tsx | 62 +++++++ .../blocks/cart-checkout/mini-cart/block.tsx | 115 ++---------- .../mini-cart/component-frontend.tsx | 3 + bin/webpack-entries.js | 4 + src/BlockTemplatePartsController.php | 163 ++++++++++++++++++ src/BlockTypes/MiniCart.php | 92 ++-------- src/BlockTypes/MiniCartContents.php | 79 +++++++++ src/BlockTypesController.php | 1 + src/Domain/Bootstrap.php | 12 ++ templates/block-template-parts/mini-cart.html | 1 + 12 files changed, 483 insertions(+), 170 deletions(-) create mode 100644 assets/js/blocks/cart-checkout/mini-cart-contents/block.tsx create mode 100644 assets/js/blocks/cart-checkout/mini-cart-contents/edit.tsx create mode 100644 assets/js/blocks/cart-checkout/mini-cart-contents/index.tsx create mode 100644 src/BlockTemplatePartsController.php create mode 100644 src/BlockTypes/MiniCartContents.php create mode 100644 templates/block-template-parts/mini-cart.html diff --git a/assets/js/blocks/cart-checkout/mini-cart-contents/block.tsx b/assets/js/blocks/cart-checkout/mini-cart-contents/block.tsx new file mode 100644 index 00000000000..76b161733c7 --- /dev/null +++ b/assets/js/blocks/cart-checkout/mini-cart-contents/block.tsx @@ -0,0 +1,104 @@ +/** + * External dependencies + */ +import { __ } from '@wordpress/i18n'; +import { useEffect, useRef } from '@wordpress/element'; +import { + usePaymentMethods, + useStoreCart, +} from '@woocommerce/base-context/hooks'; +import { TotalsItem } from '@woocommerce/blocks-checkout'; +import { CART_URL, CHECKOUT_URL } from '@woocommerce/block-settings'; +import Button from '@woocommerce/base-components/button'; +import { PaymentMethodDataProvider } from '@woocommerce/base-context'; +import { getIconsFromPaymentMethods } from '@woocommerce/base-utils'; +import PaymentMethodIcons from '@woocommerce/base-components/cart-checkout/payment-method-icons'; +import { getCurrencyFromPriceResponse } from '@woocommerce/price-format'; +import { getSetting } from '@woocommerce/settings'; + +/** + * Internal dependencies + */ +import CartLineItemsTable from '../cart/cart-line-items-table'; + +const PaymentMethodIconsElement = (): JSX.Element => { + const { paymentMethods } = usePaymentMethods(); + return ( + + ); +}; + +const MiniCartContentsBlock = (): JSX.Element => { + const { cartItems, cartIsLoading, cartTotals } = useStoreCart(); + const emptyCartRef = useRef< HTMLDivElement | null >( null ); + + const subTotal = getSetting( 'displayCartPricesIncludingTax', false ) + ? parseInt( cartTotals.total_items, 10 ) + + parseInt( cartTotals.total_items_tax, 10 ) + : parseInt( cartTotals.total_items, 10 ); + + useEffect( () => { + // If the cart has been completely emptied, move focus to empty cart + // element. + if ( ! cartIsLoading && cartItems.length === 0 ) { + if ( emptyCartRef.current instanceof HTMLElement ) { + emptyCartRef.current.focus(); + } + } + }, [ cartIsLoading, cartItems.length, emptyCartRef ] ); + + return ! cartIsLoading && cartItems.length === 0 ? ( +
+ { __( 'Cart is empty', 'woo-gutenberg-products-block' ) } +
+ ) : ( + <> +
+ +
+
+ +
+ + +
+ + + +
+ + ); +}; + +export default MiniCartContentsBlock; diff --git a/assets/js/blocks/cart-checkout/mini-cart-contents/edit.tsx b/assets/js/blocks/cart-checkout/mini-cart-contents/edit.tsx new file mode 100644 index 00000000000..68ee465cc79 --- /dev/null +++ b/assets/js/blocks/cart-checkout/mini-cart-contents/edit.tsx @@ -0,0 +1,17 @@ +/** + * External dependencies + */ +import type { ReactElement } from 'react'; +import { useBlockProps } from '@wordpress/block-editor'; + +const Edit = (): ReactElement => { + const blockProps = useBlockProps(); + + return ( +
+

Editing the mini cart contents

+
+ ); +}; + +export default Edit; diff --git a/assets/js/blocks/cart-checkout/mini-cart-contents/index.tsx b/assets/js/blocks/cart-checkout/mini-cart-contents/index.tsx new file mode 100644 index 00000000000..b35ec0a3b5b --- /dev/null +++ b/assets/js/blocks/cart-checkout/mini-cart-contents/index.tsx @@ -0,0 +1,62 @@ +/** + * External dependencies + */ +import { __ } from '@wordpress/i18n'; +import { Icon, cart } from '@woocommerce/icons'; +import { registerExperimentalBlockType } from '@woocommerce/block-settings'; + +/** + * Internal dependencies + */ +import edit from './edit'; + +const settings = { + apiVersion: 2, + title: __( 'Mini Cart Contents', 'woo-gutenberg-products-block' ), + icon: { + src: , + foreground: '#7f54b3', + }, + category: 'woocommerce', + keywords: [ __( 'WooCommerce', 'woo-gutenberg-products-block' ) ], + description: __( + 'Display a mini cart widget.', + 'woo-gutenberg-products-block' + ), + supports: { + align: false, + html: false, + multiple: false, + reusable: false, + inserter: false, + }, + attributes: { + lock: { + type: 'object', + default: { + remove: true, + move: true, + }, + }, + }, + example: { + attributes: { + isPreview: true, + }, + }, + attributes: { + isPreview: { + type: 'boolean', + default: false, + save: false, + }, + }, + + edit, + + save() { + return null; + }, +}; + +registerExperimentalBlockType( 'woocommerce/mini-cart-contents', settings ); diff --git a/assets/js/blocks/cart-checkout/mini-cart/block.tsx b/assets/js/blocks/cart-checkout/mini-cart/block.tsx index 31086d5eba8..fec41171b3b 100644 --- a/assets/js/blocks/cart-checkout/mini-cart/block.tsx +++ b/assets/js/blocks/cart-checkout/mini-cart/block.tsx @@ -3,69 +3,58 @@ */ import classnames from 'classnames'; import { __, _n, sprintf } from '@wordpress/i18n'; -import { useState, useEffect, useRef } from '@wordpress/element'; +import { RawHTML, useState, useEffect } from '@wordpress/element'; import { + renderFrontend, translateJQueryEventToNative, - getIconsFromPaymentMethods, } from '@woocommerce/base-utils'; -import { - useStoreCart, - usePaymentMethods, -} from '@woocommerce/base-context/hooks'; +import { useStoreCart } from '@woocommerce/base-context/hooks'; import Drawer from '@woocommerce/base-components/drawer'; import { formatPrice, getCurrencyFromPriceResponse, } from '@woocommerce/price-format'; import { getSetting } from '@woocommerce/settings'; -import { TotalsItem } from '@woocommerce/blocks-checkout'; -import PaymentMethodIcons from '@woocommerce/base-components/cart-checkout/payment-method-icons'; -import { CART_URL, CHECKOUT_URL } from '@woocommerce/block-settings'; -import Button from '@woocommerce/base-components/button'; -import { PaymentMethodDataProvider } from '@woocommerce/base-context'; /** * Internal dependencies */ -import CartLineItemsTable from '../cart/cart-line-items-table'; import QuantityBadge from './quantity-badge'; +import MiniCartContentsBlock from '../mini-cart-contents/block'; import './style.scss'; -const PaymentMethodIconsElement = (): JSX.Element => { - const { paymentMethods } = usePaymentMethods(); - return ( - - ); -}; - interface Props { isInitiallyOpen?: boolean; transparentButton: boolean; colorClassNames?: string; style?: Record< string, Record< string, string > >; + contents: string; } const MiniCartBlock = ( { isInitiallyOpen = false, colorClassNames, style, + contents = '', }: Props ): JSX.Element => { - const { - cartItems, - cartItemsCount, - cartIsLoading, - cartTotals, - } = useStoreCart(); + const { cartItemsCount, cartIsLoading, cartTotals } = useStoreCart(); const [ isOpen, setIsOpen ] = useState< boolean >( isInitiallyOpen ); - const emptyCartRef = useRef< HTMLDivElement | null >( null ); // We already rendered the HTML drawer placeholder, so we want to skip the // slide in animation. const [ skipSlideIn, setSkipSlideIn ] = useState< boolean >( isInitiallyOpen ); + useEffect( () => { + if ( isOpen ) { + // @todo replace with a `wc-blocks_render_blocks_frontend` event + renderFrontend( { + selector: '.wc-block-mini-cart-contents', + Block: MiniCartContentsBlock, + } ); + } + }, [ isOpen ] ); + useEffect( () => { const openMiniCart = () => { setSkipSlideIn( false ); @@ -93,16 +82,6 @@ const MiniCartBlock = ( { }; }, [] ); - useEffect( () => { - // If the cart has been completely emptied, move focus to empty cart - // element. - if ( isOpen && ! cartIsLoading && cartItems.length === 0 ) { - if ( emptyCartRef.current instanceof HTMLElement ) { - emptyCartRef.current.focus(); - } - } - }, [ isOpen, cartIsLoading, cartItems.length, emptyCartRef ] ); - const subTotal = getSetting( 'displayCartPricesIncludingTax', false ) ? parseInt( cartTotals.total_items, 10 ) + parseInt( cartTotals.total_items_tax, 10 ) @@ -125,64 +104,6 @@ const MiniCartBlock = ( { color: style?.color?.text, }; - const contents = - ! cartIsLoading && cartItems.length === 0 ? ( -
- { __( 'Cart is empty', 'woo-gutenberg-products-block' ) } -
- ) : ( - <> -
- -
-
- -
- - -
- - - -
- - ); - return ( <> + '; + } + $title = sprintf( /* translators: %d is the count of items in the cart. */ _n( @@ -302,6 +309,13 @@ protected function get_markup( $attributes ) { '; } + $part = 'mini-cart'; + $template_part = gutenberg_get_block_template( get_stylesheet() . '//' . $part, 'wp_template_part' ); + $template_part_contents = ''; + if ( $template_part && ! empty( $template_part->content ) ) { + $template_part_contents = do_blocks( $template_part->content ); + } + return '
' - . $this->get_cart_contents_markup( $cart_contents ) . - '
+ +
' + . $template_part_contents . + '
+ '; } - - /** - * Render the markup of the Cart contents. - * - * @param array $cart_contents Array of contents in the cart. - * - * @return string The HTML markup. - */ - protected function get_cart_contents_markup( $cart_contents ) { - // Force mobile styles. - return ' - - - - - - - - ' . implode( array_map( array( $this, 'get_cart_item_markup' ), $cart_contents ) ) . ' -
'; - } - - /** - * Render the skeleton of a Cart item. - * - * @return string The skeleton HTML markup. - */ - protected function get_cart_item_markup() { - return ' - - - - -
-
- -
-
- - - -
- -
- - -
-
-
- - '; - } - - /** - * Get the supports array for this block type. - * - * @see $this->register_block_type() - * @return string; - */ - protected function get_block_type_supports() { - return array_merge( - parent::get_block_type_supports(), - array( - 'html' => false, - 'multiple' => false, - 'color' => true, - '__experimentalSelector' => '.wc-block-mini-cart__button, .wc-block-mini-cart__badge', - ) - ); - } } diff --git a/src/BlockTypes/MiniCartContents.php b/src/BlockTypes/MiniCartContents.php new file mode 100644 index 00000000000..f62d24fb6b3 --- /dev/null +++ b/src/BlockTypes/MiniCartContents.php @@ -0,0 +1,79 @@ + 'wc-' . $this->block_name . '-block', + 'path' => $this->asset_api->get_block_asset_build_path( $this->block_name ), + 'dependencies' => [ 'wc-blocks' ], + ]; + return $key ? $script[ $key ] : $script; + } + + /** + * Get the frontend script handle for this block type. + * + * @see $this->register_block_type() + * @param string $key Data to get, or default to everything. + * @return array|string + */ + protected function get_block_type_script( $key = null ) { + $script = [ + 'handle' => 'wc-' . $this->block_name . '-block-frontend', + 'path' => $this->asset_api->get_block_asset_build_path( $this->block_name . '-frontend' ), + 'dependencies' => [], + ]; + return $key ? $script[ $key ] : $script; + } + + /** + * Append frontend scripts when rendering the Mini Cart block. + * + * @param array $attributes Block attributes. + * @param string $content Block content. + * + * @return string Rendered block type output. + */ + protected function render( $attributes, $content ) { + return $content . $this->get_markup(); + } + + /** + * Render the markup for the Mini Cart block. + * + * @return string The HTML markup. + */ + protected function get_markup() { + if ( is_admin() || WC()->is_rest_api_request() ) { + // In the editor we will display the placeholder, so no need to load + // real cart data and to print the markup. + return ''; + } + + return '
'; + } +} diff --git a/src/BlockTypesController.php b/src/BlockTypesController.php index d36c9d4cb4c..b742aa2d94e 100644 --- a/src/BlockTypesController.php +++ b/src/BlockTypesController.php @@ -185,6 +185,7 @@ protected function get_block_types() { if ( Package::feature()->is_experimental_build() ) { $block_types[] = 'SingleProduct'; $block_types[] = 'MiniCart'; + $block_types[] = 'MiniCartContents'; } /** diff --git a/src/Domain/Bootstrap.php b/src/Domain/Bootstrap.php index d25b2e3334c..f0f072535d3 100644 --- a/src/Domain/Bootstrap.php +++ b/src/Domain/Bootstrap.php @@ -6,6 +6,7 @@ use Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry; use Automattic\WooCommerce\Blocks\BlockTypesController; use Automattic\WooCommerce\Blocks\BlockTemplatesController; +use Automattic\WooCommerce\Blocks\BlockTemplatePartsController; use Automattic\WooCommerce\Blocks\InboxNotifications; use Automattic\WooCommerce\Blocks\Installer; use Automattic\WooCommerce\Blocks\Registry\Container; @@ -103,6 +104,9 @@ function() { $this->container->get( GoogleAnalytics::class ); $this->container->get( BlockTypesController::class ); $this->container->get( BlockTemplatesController::class ); + if ( $this->package->feature()->is_experimental_build() ) { + $this->container->get( BlockTemplatePartsController::class ); + } if ( $this->package->feature()->is_feature_plugin_build() ) { $this->container->get( PaymentsApi::class ); } @@ -235,6 +239,14 @@ function ( Container $container ) { return new BlockTemplatesController(); } ); + if ( $this->package->feature()->is_experimental_build() ) { + $this->container->register( + BlockTemplatePartsController::class, + function ( Container $container ) { + return new BlockTemplatePartsController(); + } + ); + } $this->container->register( DraftOrders::class, function( Container $container ) { diff --git a/templates/block-template-parts/mini-cart.html b/templates/block-template-parts/mini-cart.html new file mode 100644 index 00000000000..6ccda3e7236 --- /dev/null +++ b/templates/block-template-parts/mini-cart.html @@ -0,0 +1 @@ + From 85b7a9ef357099b3462c77d26889a13c42d04185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Thu, 11 Nov 2021 17:11:09 +0100 Subject: [PATCH 04/21] Remove BlockTemplatePartsController and instead use BlockTemplatesController --- src/BlockTemplatePartsController.php | 163 --------------------------- src/BlockTemplatesController.php | 77 ++++++++++--- src/Domain/Bootstrap.php | 12 -- 3 files changed, 61 insertions(+), 191 deletions(-) delete mode 100644 src/BlockTemplatePartsController.php diff --git a/src/BlockTemplatePartsController.php b/src/BlockTemplatePartsController.php deleted file mode 100644 index cdd1f910a42..00000000000 --- a/src/BlockTemplatePartsController.php +++ /dev/null @@ -1,163 +0,0 @@ -template_parts_directory = plugin_dir_path( __DIR__ ) . 'templates/' . self::TEMPLATE_PARTS_DIR_NAME; - $this->init(); - } - - /** - * Initialization method. - */ - protected function init() { - add_filter( 'get_block_template', array( $this, 'add_block_template_parts' ), 10, 3 ); - add_filter( 'get_block_templates', array( $this, 'add_block_template_parts_2' ), 10, 3 ); - // add_filter( 'default_wp_template_part_areas', array( $this, 'add_template_part_area' ), 10, 1 ); - } - - /** - * Add the block template objects to be used. - * - * @param array $query_result Array of template objects. - * @return array - */ - public function add_block_template_parts_2( $query_result, $query, $template_type ) { - if ( ! gutenberg_supports_block_templates() || 'wp_template_part' !== $template_type ) { - return $query_result; - } - - $templates_to_omit = array(); - - foreach ( $query_result as $result ) { - array_push( $templates_to_omit, $result->slug ); - } - - $template_files = $this->get_block_template_parts( $templates_to_omit ); - - foreach ( $template_files as $template_file ) { - $query_result[] = BlockTemplateUtils::gutenberg_build_template_result_from_file( $template_file, 'wp_template_part' ); - } - - return $query_result; - } - - /** - * Get and build the block template objects from the block template files. - * - * @return array - */ - public function get_block_template_parts( $templates_to_omit ) { - $template_files = BlockTemplateUtils::gutenberg_get_template_paths( $this->template_parts_directory ); - $templates = array(); - - foreach ( $template_files as $template_file ) { - $template_slug = substr( - $template_file, - strpos( $template_file, self::TEMPLATE_PARTS_DIR_NAME . DIRECTORY_SEPARATOR ) + 1 + strlen( self::TEMPLATE_PARTS_DIR_NAME ), - -5 - ); - - // If the theme already has a template then there is no need to load ours in. - if ( in_array( $template_slug, $templates_to_omit, true ) || $this->theme_has_template_part( $template_slug ) ) { - continue; - } - - $new_template_item = array( - 'title' => ucwords( str_replace( '-', ' ', $template_slug ) ), - 'slug' => $template_slug, - 'path' => $template_file, - 'theme' => get_template_directory(), - 'type' => 'wp_template_part', - 'area' => 'uncategorized', - ); - $templates[] = $new_template_item; - } - - return $templates; - } - - // public function add_template_part_area( $area_definitions ) { - // return array_merge( - // $area_definitions, - // array( - // array( - // 'area' => 'mini-cart', - // 'label' => __( 'Mini Cart', 'woo-gutenberg-products-block' ), - // 'description' => __( - // 'Lorem Ipsum', - // 'woo-gutenberg-products-block' - // ), - // 'icon' => 'footer', - // 'area_tag' => 'div', - // ), - // ) - // ); - // } - - /** - * Add the block template part objects to be used. - * - * @param array $query_result Array of template part objects. - * @return array - */ - public function add_block_template_parts( $block_template, $id, $template_type ) { - if ( ! empty( $block_template ) || $template_type !== 'wp_template_part' ) { - return $block_template; - } - - $id_parts = explode( '//', $id, 2 ); - if ( count( $id_parts ) < 2 ) { - return null; - } - $template_slug = $id_parts[1]; - - $new_template = array( - 'title' => ucwords( str_replace( '-', ' ', $template_slug ) ), - 'slug' => $template_slug, - 'path' => $this->template_parts_directory . DIRECTORY_SEPARATOR . $template_slug . '.html', - 'theme' => get_template_directory(), - 'type' => 'wp_template_part', - 'area' => 'mini-cart', - ); - $template = BlockTemplateUtils::gutenberg_build_template_result_from_file( $new_template, 'wp_template_part' ); - - return $template; - } - - /** - * Check if the theme has a template part. So we know if to load our own in or not. - * - * @param string $template_name name of the template part file without .html extension e.g. 'single-product'. - * @return boolean - */ - public function theme_has_template_part( $template_name ) { - return is_readable( get_template_directory() . '/block-template-parts/' . $template_name . '.html' ) || - is_readable( get_stylesheet_directory() . '/block-template-parts/' . $template_name . '.html' ); - } -} diff --git a/src/BlockTemplatesController.php b/src/BlockTemplatesController.php index b135569e199..59f2c8c004a 100644 --- a/src/BlockTemplatesController.php +++ b/src/BlockTemplatesController.php @@ -17,6 +17,13 @@ class BlockTemplatesController { */ private $templates_directory; + /** + * Holds the path for the directory where the block template parts will be kept. + * + * @var string + */ + private $template_parts_directory; + /** * Directory name of the block template directory. * @@ -24,11 +31,19 @@ class BlockTemplatesController { */ const TEMPLATES_DIR_NAME = 'block-templates'; + /** + * Directory name of the block template parts directory. + * + * @var string + */ + const TEMPLATE_PARTS_DIR_NAME = 'block-template-parts'; + /** * Constructor. */ public function __construct() { - $this->templates_directory = plugin_dir_path( __DIR__ ) . 'templates/' . self::TEMPLATES_DIR_NAME; + $this->templates_directory = plugin_dir_path( __DIR__ ) . 'templates/' . self::TEMPLATES_DIR_NAME; + $this->template_parts_directory = plugin_dir_path( __DIR__ ) . 'templates/' . self::TEMPLATE_PARTS_DIR_NAME; $this->init(); } @@ -116,11 +131,11 @@ public function get_single_block_template( $template, $id, $template_type ) { list( , $slug ) = $template_name_parts; // If this blocks template doesn't exist then we should just skip the function and let Gutenberg handle it. - if ( ! $this->block_template_is_available( $slug ) ) { + if ( ! $this->block_template_is_available( $slug, $template_type ) ) { return $template; } - $available_templates = $this->get_block_templates( array( $slug ) ); + $available_templates = $this->get_block_templates( array( $slug ), $template_type ); return ( is_array( $available_templates ) && count( $available_templates ) > 0 ) ? BlockTemplateUtils::gutenberg_build_template_result_from_file( $available_templates[0], $available_templates[0]->type ) : $template; @@ -135,13 +150,13 @@ public function get_single_block_template( $template, $id, $template_type ) { * @return array */ public function add_block_templates( $query_result, $query, $template_type ) { - if ( ! function_exists( 'gutenberg_supports_block_templates' ) || ! gutenberg_supports_block_templates() || 'wp_template' !== $template_type ) { + if ( ! function_exists( 'gutenberg_supports_block_templates' ) || ! gutenberg_supports_block_templates() ) { return $query_result; } $post_type = isset( $query['post_type'] ) ? $query['post_type'] : ''; $slugs = isset( $query['slug__in'] ) ? $query['slug__in'] : array(); - $template_files = $this->get_block_templates( $slugs ); + $template_files = $this->get_block_templates( $slugs, $template_type ); // @todo: Add apply_filters to _gutenberg_get_template_files() in Gutenberg to prevent duplication of logic. foreach ( $template_files as $template_file ) { @@ -242,12 +257,13 @@ function( $template ) use ( $customised_template_slugs ) { * Gets the templates saved in the database. * * @param array $slugs An array of slugs to retrieve templates for. + * @param array $template_type wp_template or wp_template_part. * * @return int[]|\WP_Post[] An array of found templates. */ - public function get_block_templates_from_db( $slugs = array() ) { + public function get_block_templates_from_db( $slugs = array(), $template_type = 'wp_template' ) { $check_query_args = array( - 'post_type' => 'wp_template', + 'post_type' => $template_type, 'posts_per_page' => -1, 'no_found_rows' => true, 'tax_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query @@ -278,16 +294,25 @@ function( $saved_woo_template ) { * * @param string[] $slugs An array of slugs to filter templates by. Templates whose slug does not match will not be returned. * @param array $already_found_templates Templates that have already been found, these are customised templates that are loaded from the database. + * @param array $template_type wp_template or wp_template_part. * * @return array Templates from the WooCommerce blocks plugin directory. */ - public function get_block_templates_from_woocommerce( $slugs, $already_found_templates ) { - $template_files = BlockTemplateUtils::gutenberg_get_template_paths( $this->templates_directory ); + public function get_block_templates_from_woocommerce( $slugs, $already_found_templates, $template_type = 'wp_template' ) { + $directory = $this->get_templates_directory( $template_type ); + $template_files = BlockTemplateUtils::gutenberg_get_template_paths( $directory ); $templates = array(); foreach ( $template_files as $template_file ) { + + if ( 'wp_template_part' === $template_type ) { + $dir_name = self::TEMPLATE_PARTS_DIR_NAME; + } else { + $dir_name = self::TEMPLATES_DIR_NAME; + } + $template_slug = substr( $template_file, - strpos( $template_file, self::TEMPLATES_DIR_NAME . DIRECTORY_SEPARATOR ) + 1 + strlen( self::TEMPLATES_DIR_NAME ), + strpos( $template_file, $dir_name . DIRECTORY_SEPARATOR ) + 1 + strlen( $dir_name ), -5 ); @@ -334,14 +359,31 @@ function ( $template ) use ( $template_slug ) { * Get and build the block template objects from the block template files. * * @param array $slugs An array of slugs to retrieve templates for. + * @param array $template_type wp_template or wp_template_part. + * * @return array */ - public function get_block_templates( $slugs = array() ) { - $templates_from_db = $this->get_block_templates_from_db( $slugs ); - $templates_from_woo = $this->get_block_templates_from_woocommerce( $slugs, $templates_from_db ); + public function get_block_templates( $slugs = array(), $template_type = 'wp_template' ) { + $templates_from_db = $this->get_block_templates_from_db( $slugs, $template_type ); + $templates_from_woo = $this->get_block_templates_from_woocommerce( $slugs, $templates_from_db, $template_type ); return array_merge( $templates_from_db, $templates_from_woo ); } + + /** + * Gets the directory where templates of a specific template type can be found. + * + * @param array $template_type wp_template or wp_template_part. + * + * @return string + */ + protected function get_templates_directory( $template_type = 'wp_template' ) { + if ( 'wp_template_part' === $template_type ) { + return $this->template_parts_directory; + } + return $this->templates_directory; + } + /** * Check if the theme has a template. So we know if to load our own in or not. * @@ -357,16 +399,19 @@ public function theme_has_template( $template_name ) { * Checks whether a block template with that name exists in Woo Blocks * * @param string $template_name Template to check. + * @param array $template_type wp_template or wp_template_part. + * * @return boolean */ - public function block_template_is_available( $template_name ) { + public function block_template_is_available( $template_name, $template_type = 'wp_template' ) { if ( ! $template_name ) { return false; } + $directory = $this->get_templates_directory( $template_type ) . '/' . $template_name . '.html'; return is_readable( - $this->templates_directory . '/' . $template_name . '.html' - ) || $this->get_block_templates( array( $template_name ) ); + $directory + ) || $this->get_block_templates( array( $template_name ), $template_type ); } /** diff --git a/src/Domain/Bootstrap.php b/src/Domain/Bootstrap.php index f0f072535d3..d25b2e3334c 100644 --- a/src/Domain/Bootstrap.php +++ b/src/Domain/Bootstrap.php @@ -6,7 +6,6 @@ use Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry; use Automattic\WooCommerce\Blocks\BlockTypesController; use Automattic\WooCommerce\Blocks\BlockTemplatesController; -use Automattic\WooCommerce\Blocks\BlockTemplatePartsController; use Automattic\WooCommerce\Blocks\InboxNotifications; use Automattic\WooCommerce\Blocks\Installer; use Automattic\WooCommerce\Blocks\Registry\Container; @@ -104,9 +103,6 @@ function() { $this->container->get( GoogleAnalytics::class ); $this->container->get( BlockTypesController::class ); $this->container->get( BlockTemplatesController::class ); - if ( $this->package->feature()->is_experimental_build() ) { - $this->container->get( BlockTemplatePartsController::class ); - } if ( $this->package->feature()->is_feature_plugin_build() ) { $this->container->get( PaymentsApi::class ); } @@ -239,14 +235,6 @@ function ( Container $container ) { return new BlockTemplatesController(); } ); - if ( $this->package->feature()->is_experimental_build() ) { - $this->container->register( - BlockTemplatePartsController::class, - function ( Container $container ) { - return new BlockTemplatePartsController(); - } - ); - } $this->container->register( DraftOrders::class, function( Container $container ) { From 414dac8402c93e151ae23f5cbee02ca24c2d7c46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Thu, 11 Nov 2021 17:13:51 +0100 Subject: [PATCH 05/21] Remove old code --- src/BlockTypes/MiniCart.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/BlockTypes/MiniCart.php b/src/BlockTypes/MiniCart.php index 6ce4db9bcb0..2ee83ff0502 100644 --- a/src/BlockTypes/MiniCart.php +++ b/src/BlockTypes/MiniCart.php @@ -268,13 +268,6 @@ protected function get_markup( $attributes ) { $cart_contents_count, wp_strip_all_tags( wc_price( $cart_contents_total ) ) ); - - if ( is_cart() || is_checkout() ) { - return '
- -
'; - } - $title = sprintf( /* translators: %d is the count of items in the cart. */ _n( From 5b41b5d45b23e614bf6110f03bb34e5b9a6183a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Fri, 12 Nov 2021 14:33:26 +0100 Subject: [PATCH 06/21] Clean up frontend rendering --- .../blocks/cart-checkout/mini-cart/block.tsx | 1 - src/BlockTypes/MiniCartContents.php | 25 ++++++------------- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/assets/js/blocks/cart-checkout/mini-cart/block.tsx b/assets/js/blocks/cart-checkout/mini-cart/block.tsx index fec41171b3b..75cf84e1f8e 100644 --- a/assets/js/blocks/cart-checkout/mini-cart/block.tsx +++ b/assets/js/blocks/cart-checkout/mini-cart/block.tsx @@ -47,7 +47,6 @@ const MiniCartBlock = ( { useEffect( () => { if ( isOpen ) { - // @todo replace with a `wc-blocks_render_blocks_frontend` event renderFrontend( { selector: '.wc-block-mini-cart-contents', Block: MiniCartContentsBlock, diff --git a/src/BlockTypes/MiniCartContents.php b/src/BlockTypes/MiniCartContents.php index f62d24fb6b3..8d255ec4f36 100644 --- a/src/BlockTypes/MiniCartContents.php +++ b/src/BlockTypes/MiniCartContents.php @@ -23,6 +23,7 @@ class MiniCartContents extends AbstractBlock { * Get the editor script handle for this block type. * * @param string $key Data to get, or default to everything. + * * @return array|string; */ protected function get_block_type_editor_script( $key = null ) { @@ -37,21 +38,18 @@ protected function get_block_type_editor_script( $key = null ) { /** * Get the frontend script handle for this block type. * - * @see $this->register_block_type() * @param string $key Data to get, or default to everything. - * @return array|string + * + * @return null */ protected function get_block_type_script( $key = null ) { - $script = [ - 'handle' => 'wc-' . $this->block_name . '-block-frontend', - 'path' => $this->asset_api->get_block_asset_build_path( $this->block_name . '-frontend' ), - 'dependencies' => [], - ]; - return $key ? $script[ $key ] : $script; + // The frontend script is a dependency of the Mini Cart block so it's + // already lazy-loaded. + return null; } /** - * Append frontend scripts when rendering the Mini Cart block. + * Render the markup for the Mini Cart contents block. * * @param array $attributes Block attributes. * @param string $content Block content. @@ -59,15 +57,6 @@ protected function get_block_type_script( $key = null ) { * @return string Rendered block type output. */ protected function render( $attributes, $content ) { - return $content . $this->get_markup(); - } - - /** - * Render the markup for the Mini Cart block. - * - * @return string The HTML markup. - */ - protected function get_markup() { if ( is_admin() || WC()->is_rest_api_request() ) { // In the editor we will display the placeholder, so no need to load // real cart data and to print the markup. From 8f6b4c2d6dad3a1dc71daa28647715a032c00fed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Fri, 12 Nov 2021 17:36:38 +0100 Subject: [PATCH 07/21] Update tests --- assets/js/blocks/cart-checkout/mini-cart/test/block.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/assets/js/blocks/cart-checkout/mini-cart/test/block.js b/assets/js/blocks/cart-checkout/mini-cart/test/block.js index 2206882fd3d..ecec699cb0d 100644 --- a/assets/js/blocks/cart-checkout/mini-cart/test/block.js +++ b/assets/js/blocks/cart-checkout/mini-cart/test/block.js @@ -23,7 +23,10 @@ import { defaultCartState } from '../../../../data/default-states'; const MiniCartBlock = ( props ) => ( - + ); @@ -77,7 +80,9 @@ describe( 'Testing cart', () => { await waitFor( () => expect( fetchMock ).toHaveBeenCalled() ); fireEvent.click( screen.getByLabelText( /items/i ) ); - expect( screen.getByText( /Cart is empty/i ) ).toBeInTheDocument(); + await waitFor( () => + expect( screen.getByText( /Cart is empty/i ) ).toBeInTheDocument() + ); expect( fetchMock ).toHaveBeenCalledTimes( 1 ); } ); From b9de74bab78201eef0d474969cf650492695d620 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Fri, 12 Nov 2021 19:45:07 +0100 Subject: [PATCH 08/21] Improve if clause --- .../base/context/hooks/cart/use-store-cart-event-listeners.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/base/context/hooks/cart/use-store-cart-event-listeners.ts b/assets/js/base/context/hooks/cart/use-store-cart-event-listeners.ts index 51896c843f5..a092913fad7 100644 --- a/assets/js/base/context/hooks/cart/use-store-cart-event-listeners.ts +++ b/assets/js/base/context/hooks/cart/use-store-cart-event-listeners.ts @@ -36,7 +36,7 @@ const setUp = (): void => { const addListeners = (): void => { setUp(); - if ( ! window.wcBlocksStoreCartListeners.count ) { + if ( window.wcBlocksStoreCartListeners.count === 0 ) { const removeJQueryAddedToCartEvent = translateJQueryEventToNative( 'added_to_cart', `wc-blocks_added_to_cart` From b2e630f9967bedf2f6a7afafedb7cd517a27061d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Fri, 12 Nov 2021 19:45:26 +0100 Subject: [PATCH 09/21] Fix wrong tests title --- assets/js/blocks/cart-checkout/mini-cart/test/block.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/blocks/cart-checkout/mini-cart/test/block.js b/assets/js/blocks/cart-checkout/mini-cart/test/block.js index ecec699cb0d..dc262298f56 100644 --- a/assets/js/blocks/cart-checkout/mini-cart/test/block.js +++ b/assets/js/blocks/cart-checkout/mini-cart/test/block.js @@ -50,7 +50,7 @@ const mockFullCart = () => { } ); }; -describe( 'Testing cart', () => { +describe( 'Testing Mini Cart', () => { beforeEach( async () => { mockFullCart(); // need to clear the store resolution state between tests. From 7714a0944d216ce529bed358f908671cfce86b3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Fri, 12 Nov 2021 19:45:53 +0100 Subject: [PATCH 10/21] Fix wrong variable name --- assets/js/blocks/cart-checkout/mini-cart/test/block.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/js/blocks/cart-checkout/mini-cart/test/block.js b/assets/js/blocks/cart-checkout/mini-cart/test/block.js index dc262298f56..86e107958dc 100644 --- a/assets/js/blocks/cart-checkout/mini-cart/test/block.js +++ b/assets/js/blocks/cart-checkout/mini-cart/test/block.js @@ -112,9 +112,9 @@ describe( 'Testing Mini Cart', () => { mockFullCart(); // eslint-disable-next-line no-undef - const removedFromCartEvent = new Event( 'wc-blocks_added_to_cart' ); + const addedToCartEvent = new Event( 'wc-blocks_added_to_cart' ); act( () => { - document.body.dispatchEvent( removedFromCartEvent ); + document.body.dispatchEvent( addedToCartEvent ); } ); await waitForElementToBeRemoved( () => From eeea1ea3b5e1415079121b4ae41d16003057e308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Fri, 12 Nov 2021 20:47:35 +0100 Subject: [PATCH 11/21] Make sure Mini Cart contents block is unmounted whem mini cart closes or unmounts --- assets/js/base/utils/render-frontend.js | 46 ++++++++++++++---- .../blocks/cart-checkout/mini-cart/block.tsx | 47 +++++++++++++++---- .../cart-checkout/mini-cart/test/block.js | 12 +++-- 3 files changed, 85 insertions(+), 20 deletions(-) diff --git a/assets/js/base/utils/render-frontend.js b/assets/js/base/utils/render-frontend.js index dc5e3dc1a38..7063352357e 100644 --- a/assets/js/base/utils/render-frontend.js +++ b/assets/js/base/utils/render-frontend.js @@ -53,17 +53,47 @@ const renderBlockInContainers = ( { }; el.classList.remove( 'is-loading' ); - render( - - }> - - - , - el - ); + renderBlock( { + Block, + container: el, + props, + attributes, + errorBoundaryProps, + } ); } ); }; +/** + * Renders a block component in a single `container` node. + * + * @param {Object} props Render props. + * @param {Function} props.Block React component to use as a + * replacement. + * @param {Node} props.container Container to replace with + * the Block component. + * @param {Object} [props.attributes] Attributes object for the + * block. + * @param {Object} [props.props] Props object for the block. + * @param {Object} [props.errorBoundaryProps] Props object for the error + * boundary. + */ +export const renderBlock = ( { + Block, + container, + attributes = {}, + props = {}, + errorBoundaryProps = {}, +} ) => { + render( + + }> + + + , + container + ); +}; + /** * Renders the block frontend in the elements matched by the selector which are * outside the wrapper elements. diff --git a/assets/js/blocks/cart-checkout/mini-cart/block.tsx b/assets/js/blocks/cart-checkout/mini-cart/block.tsx index 75cf84e1f8e..598937e4ad8 100644 --- a/assets/js/blocks/cart-checkout/mini-cart/block.tsx +++ b/assets/js/blocks/cart-checkout/mini-cart/block.tsx @@ -3,9 +3,15 @@ */ import classnames from 'classnames'; import { __, _n, sprintf } from '@wordpress/i18n'; -import { RawHTML, useState, useEffect } from '@wordpress/element'; import { - renderFrontend, + RawHTML, + useState, + useEffect, + useRef, + unmountComponentAtNode, +} from '@wordpress/element'; +import { + renderBlock, translateJQueryEventToNative, } from '@woocommerce/base-utils'; import { useStoreCart } from '@woocommerce/base-context/hooks'; @@ -45,15 +51,38 @@ const MiniCartBlock = ( { isInitiallyOpen ); + const contentsRef = useRef(); + useEffect( () => { - if ( isOpen ) { - renderFrontend( { - selector: '.wc-block-mini-cart-contents', - Block: MiniCartContentsBlock, - } ); + if ( contentsRef.current instanceof Node ) { + const container = contentsRef.current.querySelector( + '.wc-block-mini-cart-contents' + ); + if ( isOpen ) { + renderBlock( { + Block: MiniCartContentsBlock, + container, + props: { + testProp: 'test', + }, + } ); + } else { + unmountComponentAtNode( container ); + } } }, [ isOpen ] ); + useEffect( () => { + return () => { + if ( contentsRef.current instanceof Node ) { + const container = contentsRef.current.querySelector( + '.wc-block-mini-cart-contents' + ); + unmountComponentAtNode( container ); + } + }; + } ); + useEffect( () => { const openMiniCart = () => { setSkipSlideIn( false ); @@ -156,7 +185,9 @@ const MiniCartBlock = ( { } } slideIn={ ! skipSlideIn } > - { contents } +
+ { contents } +
); diff --git a/assets/js/blocks/cart-checkout/mini-cart/test/block.js b/assets/js/blocks/cart-checkout/mini-cart/test/block.js index 86e107958dc..53dcdbb806b 100644 --- a/assets/js/blocks/cart-checkout/mini-cart/test/block.js +++ b/assets/js/blocks/cart-checkout/mini-cart/test/block.js @@ -98,10 +98,12 @@ describe( 'Testing Mini Cart', () => { } ); await waitForElementToBeRemoved( () => - screen.queryByLabelText( /3 items/i ) + screen.queryByLabelText( /3 items in cart/i ) ); await waitFor( () => - expect( screen.getByLabelText( /0 items/i ) ).toBeInTheDocument() + expect( + screen.getByLabelText( /0 items in cart/i ) + ).toBeInTheDocument() ); } ); @@ -118,10 +120,12 @@ describe( 'Testing Mini Cart', () => { } ); await waitForElementToBeRemoved( () => - screen.queryByLabelText( /0 items/i ) + screen.queryByLabelText( /0 items in cart/i ) ); await waitFor( () => - expect( screen.getAllByLabelText( /3 items/i ).length > 0 ) + expect( + screen.getByLabelText( /3 items in cart/i ) + ).toBeInTheDocument() ); } ); } ); From 0238f92ca7f5cdfff759e32c73ddf8e86fb4d64c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Fri, 12 Nov 2021 20:50:28 +0100 Subject: [PATCH 12/21] Remove unnecessary waitFor --- assets/js/blocks/cart-checkout/mini-cart/test/block.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/assets/js/blocks/cart-checkout/mini-cart/test/block.js b/assets/js/blocks/cart-checkout/mini-cart/test/block.js index 53dcdbb806b..212fe5451b7 100644 --- a/assets/js/blocks/cart-checkout/mini-cart/test/block.js +++ b/assets/js/blocks/cart-checkout/mini-cart/test/block.js @@ -80,9 +80,7 @@ describe( 'Testing Mini Cart', () => { await waitFor( () => expect( fetchMock ).toHaveBeenCalled() ); fireEvent.click( screen.getByLabelText( /items/i ) ); - await waitFor( () => - expect( screen.getByText( /Cart is empty/i ) ).toBeInTheDocument() - ); + expect( screen.getByText( /Cart is empty/i ) ).toBeInTheDocument(); expect( fetchMock ).toHaveBeenCalledTimes( 1 ); } ); From cdfcb72064fec2512f2cfe083f0f7c613a1cc121 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Mon, 15 Nov 2021 09:57:02 +0100 Subject: [PATCH 13/21] Fix PaymentMethodDataProvider wrong children type --- .../payment-methods/payment-method-data-context.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/base/context/providers/cart-checkout/payment-methods/payment-method-data-context.tsx b/assets/js/base/context/providers/cart-checkout/payment-methods/payment-method-data-context.tsx index 919185a2a66..c8c6da01254 100644 --- a/assets/js/base/context/providers/cart-checkout/payment-methods/payment-method-data-context.tsx +++ b/assets/js/base/context/providers/cart-checkout/payment-methods/payment-method-data-context.tsx @@ -60,7 +60,7 @@ export const usePaymentMethodDataContext = (): PaymentMethodDataContextType => { export const PaymentMethodDataProvider = ( { children, }: { - children: React.ReactChildren; + children: React.ReactNode; } ): JSX.Element => { const { isProcessing: checkoutIsProcessing, From 7c1fc59ded04c3c54c50f7330c960624c761bc27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Mon, 15 Nov 2021 10:16:53 +0100 Subject: [PATCH 14/21] TypeScript fixes --- .../js/blocks/cart-checkout/mini-cart/block.tsx | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/assets/js/blocks/cart-checkout/mini-cart/block.tsx b/assets/js/blocks/cart-checkout/mini-cart/block.tsx index 598937e4ad8..746c3397193 100644 --- a/assets/js/blocks/cart-checkout/mini-cart/block.tsx +++ b/assets/js/blocks/cart-checkout/mini-cart/block.tsx @@ -51,13 +51,16 @@ const MiniCartBlock = ( { isInitiallyOpen ); - const contentsRef = useRef(); + const contentsRef = useRef() as React.MutableRefObject< HTMLDivElement >; useEffect( () => { - if ( contentsRef.current instanceof Node ) { + if ( contentsRef.current instanceof Element ) { const container = contentsRef.current.querySelector( '.wc-block-mini-cart-contents' ); + if ( ! container ) { + return; + } if ( isOpen ) { renderBlock( { Block: MiniCartContentsBlock, @@ -73,12 +76,16 @@ const MiniCartBlock = ( { }, [ isOpen ] ); useEffect( () => { + const contentsNode = contentsRef.current as unknown; + return () => { - if ( contentsRef.current instanceof Node ) { - const container = contentsRef.current.querySelector( + if ( contentsNode instanceof Element ) { + const container = contentsNode.querySelector( '.wc-block-mini-cart-contents' ); - unmountComponentAtNode( container ); + if ( container ) { + unmountComponentAtNode( container ); + } } }; } ); From fe0cb736a8c4fd964c3e404afbf044a433f0189a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Mon, 15 Nov 2021 10:20:34 +0100 Subject: [PATCH 15/21] Make comment shorter --- src/BlockTypes/MiniCartContents.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/BlockTypes/MiniCartContents.php b/src/BlockTypes/MiniCartContents.php index 8d255ec4f36..c5eeec0c0cb 100644 --- a/src/BlockTypes/MiniCartContents.php +++ b/src/BlockTypes/MiniCartContents.php @@ -58,8 +58,8 @@ protected function get_block_type_script( $key = null ) { */ protected function render( $attributes, $content ) { if ( is_admin() || WC()->is_rest_api_request() ) { - // In the editor we will display the placeholder, so no need to load - // real cart data and to print the markup. + // In the editor we will display the placeholder, so no need to + // print the markup. return ''; } From 5aa9c5a67733ca47dbad6352520eae7bacbad196 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Mon, 15 Nov 2021 10:31:49 +0100 Subject: [PATCH 16/21] Remove test code --- assets/js/blocks/cart-checkout/mini-cart/block.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/assets/js/blocks/cart-checkout/mini-cart/block.tsx b/assets/js/blocks/cart-checkout/mini-cart/block.tsx index 746c3397193..47c9c097f16 100644 --- a/assets/js/blocks/cart-checkout/mini-cart/block.tsx +++ b/assets/js/blocks/cart-checkout/mini-cart/block.tsx @@ -65,9 +65,6 @@ const MiniCartBlock = ( { renderBlock( { Block: MiniCartContentsBlock, container, - props: { - testProp: 'test', - }, } ); } else { unmountComponentAtNode( container ); From 797d70e74dcc5a1ec3d30c615cb492e4f86daa9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Mon, 15 Nov 2021 10:58:13 +0100 Subject: [PATCH 17/21] Fix contant unmounts of Mini Cart contents block --- assets/js/blocks/cart-checkout/mini-cart/block.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/assets/js/blocks/cart-checkout/mini-cart/block.tsx b/assets/js/blocks/cart-checkout/mini-cart/block.tsx index 47c9c097f16..d181ee3c363 100644 --- a/assets/js/blocks/cart-checkout/mini-cart/block.tsx +++ b/assets/js/blocks/cart-checkout/mini-cart/block.tsx @@ -73,9 +73,8 @@ const MiniCartBlock = ( { }, [ isOpen ] ); useEffect( () => { - const contentsNode = contentsRef.current as unknown; - return () => { + const contentsNode = contentsRef.current as unknown; if ( contentsNode instanceof Element ) { const container = contentsNode.querySelector( '.wc-block-mini-cart-contents' @@ -85,7 +84,7 @@ const MiniCartBlock = ( { } } }; - } ); + }, [] ); useEffect( () => { const openMiniCart = () => { From ff180eb003a7d2d0f5af2924d7eb5da5ba686b5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Wed, 17 Nov 2021 15:01:05 +0100 Subject: [PATCH 18/21] Fix wrong template_type passed --- src/BlockTemplatesController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/BlockTemplatesController.php b/src/BlockTemplatesController.php index 59f2c8c004a..bbee4fb3757 100644 --- a/src/BlockTemplatesController.php +++ b/src/BlockTemplatesController.php @@ -187,7 +187,7 @@ function( $query_result_template ) use ( $template_file ) { // It would be custom if the template was modified in the editor, so if it's not custom we can load it from // the filesystem. if ( 'custom' !== $template_file->source ) { - $template = BlockTemplateUtils::gutenberg_build_template_result_from_file( $template_file, 'wp_template' ); + $template = BlockTemplateUtils::gutenberg_build_template_result_from_file( $template_file, $template_type ); } else { $template_file->title = BlockTemplateUtils::convert_slug_to_title( $template_file->slug ); $query_result[] = $template_file; @@ -343,7 +343,7 @@ function ( $template ) use ( $template_slug ) { 'slug' => $template_slug, 'id' => 'woocommerce//' . $template_slug, 'path' => $template_file, - 'type' => 'wp_template', + 'type' => $template_type, 'theme' => 'woocommerce', 'source' => 'woocommerce', 'title' => BlockTemplateUtils::convert_slug_to_title( $template_slug ), From c9c2f57283cfa30669fabb69f2a831843d42acaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Thu, 18 Nov 2021 17:26:47 +0100 Subject: [PATCH 19/21] Set Template part area to 'uncategorized' --- src/Utils/BlockTemplateUtils.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Utils/BlockTemplateUtils.php b/src/Utils/BlockTemplateUtils.php index 23c090a3b3f..1ce54846f57 100644 --- a/src/Utils/BlockTemplateUtils.php +++ b/src/Utils/BlockTemplateUtils.php @@ -109,6 +109,9 @@ public static function gutenberg_build_template_result_from_post( $post ) { $template->has_theme_file = $has_theme_file; $template->is_custom = true; $template->post_types = array(); // Don't appear in any Edit Post template selector dropdown. + if ( 'wp_template_part' === $post->post_type ) { + $template->area = 'uncategorized'; + } return $template; } @@ -137,6 +140,9 @@ public static function gutenberg_build_template_result_from_file( $template_file $template->has_theme_file = true; $template->is_custom = false; // Templates loaded from the filesystem aren't custom, ones that have been edited and loaded from the DB are. $template->post_types = array(); // Don't appear in any Edit Post template selector dropdown. + if ( 'wp_template_part' === $template_type ) { + $template->area = 'uncategorized'; + } return $template; } From 5ee58d2142d78592be2256fe50aaf288ca633f90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Fri, 19 Nov 2021 12:08:22 +0100 Subject: [PATCH 20/21] Set Template part area to the correct value --- src/Utils/BlockTemplateUtils.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Utils/BlockTemplateUtils.php b/src/Utils/BlockTemplateUtils.php index 1ce54846f57..8cc24edcbff 100644 --- a/src/Utils/BlockTemplateUtils.php +++ b/src/Utils/BlockTemplateUtils.php @@ -110,7 +110,10 @@ public static function gutenberg_build_template_result_from_post( $post ) { $template->is_custom = true; $template->post_types = array(); // Don't appear in any Edit Post template selector dropdown. if ( 'wp_template_part' === $post->post_type ) { - $template->area = 'uncategorized'; + $type_terms = get_the_terms( $post, 'wp_template_part_area' ); + if ( ! is_wp_error( $type_terms ) && false !== $type_terms ) { + $template->area = $type_terms[0]->name; + } } return $template; @@ -141,7 +144,11 @@ public static function gutenberg_build_template_result_from_file( $template_file $template->is_custom = false; // Templates loaded from the filesystem aren't custom, ones that have been edited and loaded from the DB are. $template->post_types = array(); // Don't appear in any Edit Post template selector dropdown. if ( 'wp_template_part' === $template_type ) { - $template->area = 'uncategorized'; + if ( 'mini-cart' === $template_file->slug ) { + $template->area = 'mini-cart'; + } else { + $template->area = 'uncategorized'; + } } return $template; } From 51930edda5955e95497df145add49d629d89c26d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Fri, 19 Nov 2021 12:30:42 +0100 Subject: [PATCH 21/21] Move template dir check outside loop --- src/BlockTemplatesController.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/BlockTemplatesController.php b/src/BlockTemplatesController.php index bbee4fb3757..fa448a53dc1 100644 --- a/src/BlockTemplatesController.php +++ b/src/BlockTemplatesController.php @@ -302,14 +302,14 @@ public function get_block_templates_from_woocommerce( $slugs, $already_found_tem $directory = $this->get_templates_directory( $template_type ); $template_files = BlockTemplateUtils::gutenberg_get_template_paths( $directory ); $templates = array(); - foreach ( $template_files as $template_file ) { - if ( 'wp_template_part' === $template_type ) { - $dir_name = self::TEMPLATE_PARTS_DIR_NAME; - } else { - $dir_name = self::TEMPLATES_DIR_NAME; - } + if ( 'wp_template_part' === $template_type ) { + $dir_name = self::TEMPLATE_PARTS_DIR_NAME; + } else { + $dir_name = self::TEMPLATES_DIR_NAME; + } + foreach ( $template_files as $template_file ) { $template_slug = substr( $template_file, strpos( $template_file, $dir_name . DIRECTORY_SEPARATOR ) + 1 + strlen( $dir_name ),