Update Filter Products by Price block to work with PHP templates (https://github.com/woocommerce/woocommerce-blocks/pull/6146)

* Update Filter Products by Price block to work with PHP templates

* Reformat param formatting

* Add check for PHP template

* window guards and comments for context

* Add comment to page reload

* Addressed code review feedback

* Fix setMinPriceQuery and setMaxPriceQuery values

* Remove unnecessary snake_case comment and update newUrl to assign to window.location.href.

* package-lock.json update

Co-authored-by: tjcafferkey <tjcafferkey@gmail.com>
This commit is contained in:
Albert Juhé Lluveras 2022-04-05 12:52:35 +02:00 committed by GitHub
parent e15d516163
commit 58c649e971
4 changed files with 6855 additions and 10020 deletions

View File

@ -12,6 +12,8 @@ import PriceSlider from '@woocommerce/base-components/price-slider';
import { useDebouncedCallback } from 'use-debounce';
import PropTypes from 'prop-types';
import { getCurrencyFromPriceResponse } from '@woocommerce/price-format';
import { getSetting } from '@woocommerce/settings';
import { getQueryArg, addQueryArgs, removeQueryArgs } from '@wordpress/url';
/**
* Internal dependencies
@ -19,6 +21,43 @@ import { getCurrencyFromPriceResponse } from '@woocommerce/price-format';
import usePriceConstraints from './use-price-constraints.js';
import './style.scss';
/**
* Returns specified parameter from URL
*
* @param {string} paramName Parameter you want the value of.
*/
function findGetParameter( paramName ) {
if ( ! window ) {
return null;
}
return getQueryArg( window.location.href, paramName );
}
/**
* Formats filter values into a string for the URL parameters needed for filtering PHP templates.
*
* @param {string} url Current page URL.
* @param {Object} params Parameters and their constraints.
*
* @return {string} New URL with query parameters in it.
*/
function formatParams( url, params ) {
const paramObject = {};
for ( const [ key, value ] of Object.entries( params ) ) {
if ( value ) {
paramObject[ key ] = ( value / 100 ).toString();
} else {
delete paramObject[ key ];
}
}
// Clean the URL before we add our new query parameters to it.
const cleanUrl = removeQueryArgs( url, ...Object.keys( params ) );
return addQueryArgs( cleanUrl, paramObject );
}
/**
* Component displaying a price filter.
*
@ -27,13 +66,21 @@ import './style.scss';
* @param {boolean} props.isEditor Whether in editor context or not.
*/
const PriceFilterBlock = ( { attributes, isEditor = false } ) => {
const filteringForPhpTemplate = getSetting(
'is_rendering_php_template',
''
);
const minPriceParam = findGetParameter( 'min_price' );
const maxPriceParam = findGetParameter( 'max_price' );
const [ minPriceQuery, setMinPriceQuery ] = useQueryStateByKey(
'min_price',
null
Number( minPriceParam ) * 100 || null
);
const [ maxPriceQuery, setMaxPriceQuery ] = useQueryStateByKey(
'max_price',
null
Number( maxPriceParam ) * 100 || null
);
const [ queryState ] = useQueryStateByContext();
const { results, isLoading } = useCollectionData( {
@ -41,8 +88,12 @@ const PriceFilterBlock = ( { attributes, isEditor = false } ) => {
queryState,
} );
const [ minPrice, setMinPrice ] = useState();
const [ maxPrice, setMaxPrice ] = useState();
const [ minPrice, setMinPrice ] = useState(
Number( minPriceParam ) * 100 || null
);
const [ maxPrice, setMaxPrice ] = useState(
Number( maxPriceParam ) * 100 || null
);
const currency = getCurrencyFromPriceResponse( results.price_range );
@ -59,14 +110,38 @@ const PriceFilterBlock = ( { attributes, isEditor = false } ) => {
// Updates the query based on slider values.
const onSubmit = useCallback(
( newMinPrice, newMaxPrice ) => {
setMinPriceQuery(
newMinPrice === minConstraint ? undefined : newMinPrice
);
setMaxPriceQuery(
newMaxPrice === maxConstraint ? undefined : newMaxPrice
);
const finalMaxPrice =
newMaxPrice >= Number( maxConstraint )
? undefined
: newMaxPrice;
const finalMinPrice =
newMinPrice <= Number( minConstraint )
? undefined
: newMinPrice;
// For block templates that render the PHP Classic Template block we need to add the filters as params and reload the page.
if ( filteringForPhpTemplate && window ) {
const newUrl = formatParams( window.location.href, {
min_price: finalMinPrice,
max_price: finalMaxPrice,
} );
// If the params have changed, lets reload the page.
if ( window.location.href !== newUrl ) {
window.location.href = newUrl;
}
} else {
setMinPriceQuery( finalMinPrice );
setMaxPriceQuery( finalMaxPrice );
}
},
[ minConstraint, maxConstraint, setMinPriceQuery, setMaxPriceQuery ]
[
minConstraint,
maxConstraint,
setMinPriceQuery,
setMaxPriceQuery,
filteringForPhpTemplate,
]
);
// Updates the query after a short delay.

File diff suppressed because it is too large Load Diff

View File

@ -214,6 +214,7 @@
"@wordpress/plugins": "4.0.7",
"@wordpress/primitives": "3.0.4",
"@wordpress/server-side-render": "3.0.17",
"@wordpress/url": "^3.6.0",
"@wordpress/wordcount": "3.2.3",
"classnames": "2.3.1",
"compare-versions": "3.6.0",

View File

@ -60,6 +60,12 @@ class ClassicTemplate extends AbstractDynamicBlock {
if ( 'single-product' === $attributes['template'] ) {
return $this->render_single_product();
} elseif ( in_array( $attributes['template'], $archive_templates, true ) ) {
// We need to set this so that our product filters can detect if it's a PHP template.
$this->asset_data_registry->add(
'is_rendering_php_template',
true,
null
);
return $this->render_archive_product();
} else {
ob_start();