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

Change default rows for product grid blocks to 3 #1613

Merged
merged 17 commits into from Jan 22, 2020
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
48 changes: 40 additions & 8 deletions assets/js/blocks/products/all-products/index.js
Expand Up @@ -5,19 +5,19 @@ import { __ } from '@wordpress/i18n';
import { InnerBlocks } from '@wordpress/block-editor';
import { registerBlockType } from '@wordpress/blocks';
import Gridicon from 'gridicons';
import { withDefaultAttributes } from '@woocommerce/block-hocs';

/**
* Internal dependencies
*/
import Editor from './edit';
import sharedAttributes from '../attributes';
import { getBlockClassName } from '../utils.js';
import { attributes as sharedAttributes, defaults } from '../attributes';
import { getBlockClassName, setBlockAttributeDefaults } from '../utils.js';
import '../../../atomic/blocks/product';

/**
* Register and run the "All Products" block.
*/
registerBlockType( 'woocommerce/all-products', {
const { addFilter } = wp.hooks;

const blockSettings = {
title: __( 'All Products', 'woo-gutenberg-products-block' ),
icon: {
src: <Gridicon icon="grid" />,
Expand All @@ -42,7 +42,7 @@ registerBlockType( 'woocommerce/all-products', {
attributes: {
...sharedAttributes,
},

defaults,
/**
* Renders and manages the block.
*
Expand All @@ -51,7 +51,6 @@ registerBlockType( 'woocommerce/all-products', {
edit( props ) {
return <Editor { ...props } />;
},

/**
* Save the props to post content.
*
Expand All @@ -74,4 +73,37 @@ registerBlockType( 'woocommerce/all-products', {
</div>
);
},
};

/**
* Register and run the "All Products" block.
*/
registerBlockType( 'woocommerce/all-products', {
...blockSettings,
/**
* Deprecation rule to handle the previous default rows which was 1 instead of 3.
*/
deprecated: [
{
attributes: Object.assign( blockSettings.attributes, {
rows: {
type: 'number',
default: 1,
},
} ),
mikejolley marked this conversation as resolved.
Show resolved Hide resolved
save: blockSettings.save,
},
],
} );

addFilter(
'blocks.getBlockAttributes',
'woocommerce-blocks/get-block-attributes',
setBlockAttributeDefaults
);

addFilter(
'editor.BlockListBlock',
'woocommerce-blocks/with-default-attributes',
withDefaultAttributes
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed in slack, let's move these into their own location. Since this is an editor only thing, we can probably put this in js/editor/filters.js then in the main entry file (which is built to the wc-blocks handle) we can import it directly. This will also require updating the sideEffects property in package.json to keep webpack from dropping the import during treeshaking.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added to assets/js/filters and handled in sideEffects. You can see the latest code now.

28 changes: 13 additions & 15 deletions assets/js/blocks/products/attributes.js
Expand Up @@ -8,57 +8,55 @@ import { DEFAULT_COLUMNS, DEFAULT_ROWS } from '@woocommerce/block-settings';
*/
import { DEFAULT_PRODUCT_LIST_LAYOUT } from './base-utils';

export default {
export const defaults = {
columns: DEFAULT_COLUMNS,
rows: DEFAULT_ROWS,
alignButtons: false,
contentVisibility: {
orderBy: true,
},
orderby: 'date',
layoutConfig: DEFAULT_PRODUCT_LIST_LAYOUT,
isPreview: false,
};

export const attributes = {
/**
* Number of columns.
*/
columns: {
type: 'number',
default: DEFAULT_COLUMNS,
},

/**
* Number of rows.
*/
rows: {
type: 'number',
default: DEFAULT_ROWS,
},

/**
* How to align cart buttons.
*/
alignButtons: {
type: 'boolean',
default: false,
},

/**
* Content visibility setting
*/
contentVisibility: {
type: 'object',
default: {
orderBy: true,
},
},

/**
* Order to use for the products listing.
*/
orderby: {
type: 'string',
default: 'date',
},

/**
* Layout config.
*/
layoutConfig: {
type: 'array',
default: DEFAULT_PRODUCT_LIST_LAYOUT,
},

/**
* Are we previewing?
*/
Expand Down
35 changes: 30 additions & 5 deletions assets/js/blocks/products/utils.js
Expand Up @@ -11,14 +11,39 @@ export const getBlockClassName = ( blockClassName, attributes ) => {
const { className, contentVisibility } = attributes;

return classNames( blockClassName, className, {
'has-image': contentVisibility.image,
'has-title': contentVisibility.title,
'has-rating': contentVisibility.rating,
'has-price': contentVisibility.price,
'has-button': contentVisibility.button,
'has-image': contentVisibility && contentVisibility.image,
'has-title': contentVisibility && contentVisibility.title,
'has-rating': contentVisibility && contentVisibility.rating,
'has-price': contentVisibility && contentVisibility.price,
'has-button': contentVisibility && contentVisibility.button,
} );
};

/**
* Adjust attributes on load to set defaults so default attributes get saved.
*
* Ref: https://github.com/WordPress/gutenberg/issues/7342
*
* @param {Object} blockAttributes Original block attributes.
* @param {Object} blockType Block type settings.
*
* @return {Object} Filtered block attributes.
*/
export const setBlockAttributeDefaults = ( blockAttributes, blockType ) => {
Object.keys( blockType.attributes ).map( ( key ) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to only run this on our blocks. We're using a non-official property on the block config here, there's risk another block somewhere might be using defaults in a different way.

This also applies to the other filter implementations in this pull (I won't repeat this comment for withDefaultAttributes).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Added a check for the block prefix.

if (
blockAttributes[ key ] === undefined &&
blockType.defaults !== undefined &&
blockType.defaults[ key ] !== undefined
) {
blockAttributes[ key ] = blockType.defaults[ key ];
}
mikejolley marked this conversation as resolved.
Show resolved Hide resolved
return key;
} );

return blockAttributes;
};

export const renderNoProductsPlaceholder = ( blockTitle, blockIcon ) => (
<Placeholder
className="wc-block-products"
Expand Down
5 changes: 2 additions & 3 deletions assets/js/hocs/index.js
Expand Up @@ -5,7 +5,6 @@ export { default as withFeedbackPrompt } from './with-feedback-prompt';
export { default as withProduct } from './with-product';
export { default as withProductVariations } from './with-product-variations';
export { default as withSearchedProducts } from './with-searched-products';
export {
default as withTransformSingleSelectToMultipleSelect,
} from './with-transform-single-select-to-multiple-select';
export { default as withTransformSingleSelectToMultipleSelect } from './with-transform-single-select-to-multiple-select';
export { default as withRestApiHydration } from './with-rest-api-hydration';
export { default as withDefaultAttributes } from './with-default-attributes';
40 changes: 40 additions & 0 deletions assets/js/hocs/with-default-attributes.js
@@ -0,0 +1,40 @@
/**
* External dependencies
*/
import { createHigherOrderComponent } from '@wordpress/compose';
const { getBlockType } = wp.blocks;

/**
* withDefaultAttributes
*
* Fixes a bug where block attribute "default values" are not saved in serialized data.
* Extend the default BlockListBlock component and apply default values allowing
* Gutenberg to serialize the settings (normally ignored).
*
* @see https://github.com/WordPress/gutenberg/issues/7342#issuecomment-435371583
*
* @param object BlockListBlock The BlockListBlock element.
*/
const withDefaultAttributes = createHigherOrderComponent(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be moved outside of the js/hocs folder. The hoc here has a very specific use case so it'd be nice to keep it separate for the more general hoc usages. probably would be good to keep it in editor/hocs (staying connected with the filters there) maybe?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about in the filter js file itself since it's so specific?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done 👍

( BlockListBlock ) => {
return function( props ) {
const blockType = getBlockType( props.block.name );

Object.keys( blockType.attributes ).map( ( key ) => {
if (
props.attributes[ key ] === undefined &&
blockType.defaults !== undefined &&
blockType.defaults[ key ] !== undefined
) {
props.attributes[ key ] = blockType.defaults[ key ];
}
return key;
} );

return <BlockListBlock { ...props } />;
};
},
'withDefaultAttributes'
);

export default withDefaultAttributes;
2 changes: 1 addition & 1 deletion assets/js/settings/blocks/constants.js
Expand Up @@ -13,7 +13,7 @@ export const MIN_COLUMNS = getSetting( 'min_columns', 1 );
export const DEFAULT_COLUMNS = getSetting( 'default_columns', 3 );
export const MAX_ROWS = getSetting( 'max_rows', 6 );
export const MIN_ROWS = getSetting( 'min_rows', 1 );
export const DEFAULT_ROWS = getSetting( 'default_rows', 2 );
export const DEFAULT_ROWS = getSetting( 'default_rows', 3 );
export const MIN_HEIGHT = getSetting( 'min_height', 500 );
export const DEFAULT_HEIGHT = getSetting( 'default_height', 500 );
export const PLACEHOLDER_IMG_SRC = getSetting( 'placeholderImgSrc', '' );
Expand Down
2 changes: 1 addition & 1 deletion src/Assets.php
Expand Up @@ -108,7 +108,7 @@ public static function get_wc_block_data( $settings ) {
'default_columns' => wc_get_theme_support( 'product_blocks::default_columns', 3 ),
'min_rows' => wc_get_theme_support( 'product_blocks::min_rows', 1 ),
'max_rows' => wc_get_theme_support( 'product_blocks::max_rows', 6 ),
'default_rows' => wc_get_theme_support( 'product_blocks::default_rows', 1 ),
'default_rows' => wc_get_theme_support( 'product_blocks::default_rows', 3 ),
'thumbnail_size' => wc_get_theme_support( 'thumbnail_image_width', 300 ),
'placeholderImgSrc' => wc_placeholder_img_src(),
'min_height' => wc_get_theme_support( 'featured_block::min_height', 500 ),
Expand Down
4 changes: 2 additions & 2 deletions src/BlockTypes/AbstractProductGrid.php
Expand Up @@ -46,7 +46,7 @@ protected function get_attributes() {
return array(
'className' => $this->get_schema_string(),
'columns' => $this->get_schema_number( wc_get_theme_support( 'product_blocks::default_columns', 3 ) ),
'rows' => $this->get_schema_number( wc_get_theme_support( 'product_blocks::default_rows', 1 ) ),
'rows' => $this->get_schema_number( wc_get_theme_support( 'product_blocks::default_rows', 3 ) ),
'categories' => $this->get_schema_list_ids(),
'catOperator' => array(
'type' => 'string',
Expand Down Expand Up @@ -122,7 +122,7 @@ protected function parse_attributes( $attributes ) {
// These should match what's set in JS `registerBlockType`.
$defaults = array(
'columns' => wc_get_theme_support( 'product_blocks::default_columns', 3 ),
'rows' => wc_get_theme_support( 'product_blocks::default_rows', 1 ),
'rows' => wc_get_theme_support( 'product_blocks::default_rows', 3 ),
'alignButtons' => false,
'categories' => array(),
'catOperator' => 'any',
Expand Down
2 changes: 1 addition & 1 deletion src/BlockTypes/ProductTag.php
Expand Up @@ -45,7 +45,7 @@ protected function get_attributes() {
return array(
'className' => $this->get_schema_string(),
'columns' => $this->get_schema_number( wc_get_theme_support( 'product_blocks::default_columns', 3 ) ),
'rows' => $this->get_schema_number( wc_get_theme_support( 'product_blocks::default_rows', 1 ) ),
'rows' => $this->get_schema_number( wc_get_theme_support( 'product_blocks::default_rows', 3 ) ),
'contentVisibility' => $this->get_schema_content_visibility(),
'align' => $this->get_schema_align(),
'alignButtons' => $this->get_schema_boolean( false ),
Expand Down
2 changes: 1 addition & 1 deletion src/BlockTypes/ProductsByAttribute.php
Expand Up @@ -73,7 +73,7 @@ protected function get_attributes() {
'contentVisibility' => $this->get_schema_content_visibility(),
'editMode' => $this->get_schema_boolean( true ),
'orderby' => $this->get_schema_orderby(),
'rows' => $this->get_schema_number( wc_get_theme_support( 'product_blocks::default_rows', 1 ) ),
'rows' => $this->get_schema_number( wc_get_theme_support( 'product_blocks::default_rows', 3 ) ),
'isPreview' => $this->get_schema_boolean( false ),
);
}
Expand Down