This repository has been archived by the owner on Feb 23, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 219
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Register patterns under
patterns
folder and add filters pattern (#6861
) * POC about registering patterns * POC load patterns from `/patterns` folder * Change class name and remove unnecessary comment * Add all four blocks to the filters pattern * Add all 4 blocks to the block type to allow for transformations * Add internal * Improve filters name * Extract regex to constants * Add class description * Rename and move class * Fix wrong imports * Address feedback * Early return from condition * Fix wrong block type
- Loading branch information
Showing
4 changed files
with
242 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?php | ||
/** | ||
* Title: WooCommerce Product Filters | ||
* Slug: woocommerce-blocks/product-filters | ||
* Categories: WooCommerce | ||
* Block Types: woocommerce/active-filters, woocommerce/price-filter, woocommerce/attribute-filter, woocommerce/stock-filter | ||
*/ | ||
?> | ||
|
||
<!-- wp:woocommerce/active-filters --> | ||
<div class="wp-block-woocommerce-active-filters is-loading" data-display-style="list" data-heading="Active filters" data-heading-level="3"><span aria-hidden="true" class="wc-block-active-product-filters__placeholder"></span></div> | ||
<!-- /wp:woocommerce/active-filters --> | ||
|
||
<!-- wp:woocommerce/price-filter --> | ||
<div class="wp-block-woocommerce-price-filter is-loading" data-showinputfields="true" data-showfilterbutton="false" data-heading="Filter by price" data-heading-level="3"><span aria-hidden="true" class="wc-block-product-categories__placeholder"></span></div> | ||
<!-- /wp:woocommerce/price-filter --> | ||
|
||
<!-- wp:woocommerce/attribute-filter --> | ||
<div class="wp-block-woocommerce-attribute-filter is-loading" data-attribute-id="0" data-show-counts="true" data-query-type="or" data-heading="Filter by attribute" data-heading-level="3"><span aria-hidden="true" class="wc-block-product-attribute-filter__placeholder"></span></div> | ||
<!-- /wp:woocommerce/attribute-filter --> | ||
|
||
<!-- wp:woocommerce/stock-filter --> | ||
<div class="wp-block-woocommerce-stock-filter is-loading" data-show-counts="true" data-heading="Filter by stock status" data-heading-level="3"><span aria-hidden="true" class="wc-block-product-stock-filter__placeholder"></span></div> | ||
<!-- /wp:woocommerce/stock-filter --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
<?php | ||
namespace Automattic\WooCommerce\Blocks; | ||
|
||
use Automattic\WooCommerce\Blocks\Domain\Package; | ||
|
||
/** | ||
* Registers patterns under the `./patterns/` directory. | ||
* Each pattern is defined as a PHP file and defines its metadata using plugin-style headers. | ||
* The minimum required definition is: | ||
* | ||
* /** | ||
* * Title: My Pattern | ||
* * Slug: my-theme/my-pattern | ||
* * | ||
* | ||
* The output of the PHP source corresponds to the content of the pattern, e.g.: | ||
* | ||
* <main><p><?php echo "Hello"; ?></p></main> | ||
* | ||
* Other settable fields include: | ||
* | ||
* - Description | ||
* - Viewport Width | ||
* - Categories (comma-separated values) | ||
* - Keywords (comma-separated values) | ||
* - Block Types (comma-separated values) | ||
* - Inserter (yes/no) | ||
* | ||
* @internal | ||
*/ | ||
class BlockPatterns { | ||
const SLUG_REGEX = '/^[A-z0-9\/_-]+$/'; | ||
const COMMA_SEPARATED_REGEX = '/[\s,]+/'; | ||
|
||
/** | ||
* Path to the patterns directory. | ||
* | ||
* @var string $patterns_path | ||
*/ | ||
private $patterns_path; | ||
|
||
/** | ||
* Constructor for class | ||
* | ||
* @param Package $package An instance of Package. | ||
*/ | ||
public function __construct( Package $package ) { | ||
$this->patterns_path = $package->get_path( 'patterns' ); | ||
|
||
add_action( 'init', array( $this, 'register_block_patterns' ) ); | ||
} | ||
|
||
/** | ||
* Registers the block patterns and categories under `./patterns/`. | ||
*/ | ||
public function register_block_patterns() { | ||
if ( ! class_exists( 'WP_Block_Patterns_Registry' ) ) { | ||
return; | ||
} | ||
|
||
$default_headers = array( | ||
'title' => 'Title', | ||
'slug' => 'Slug', | ||
'description' => 'Description', | ||
'viewportWidth' => 'Viewport Width', | ||
'categories' => 'Categories', | ||
'keywords' => 'Keywords', | ||
'blockTypes' => 'Block Types', | ||
'inserter' => 'Inserter', | ||
); | ||
|
||
if ( ! file_exists( $this->patterns_path ) ) { | ||
return; | ||
} | ||
|
||
$files = glob( $this->patterns_path . '/*.php' ); | ||
if ( ! $files ) { | ||
return; | ||
} | ||
|
||
foreach ( $files as $file ) { | ||
$pattern_data = get_file_data( $file, $default_headers ); | ||
|
||
if ( empty( $pattern_data['slug'] ) ) { | ||
_doing_it_wrong( | ||
'register_block_patterns', | ||
esc_html( | ||
sprintf( | ||
/* translators: %s: file name. */ | ||
__( 'Could not register file "%s" as a block pattern ("Slug" field missing)', 'woo-gutenberg-products-block' ), | ||
$file | ||
) | ||
), | ||
'6.0.0' | ||
); | ||
continue; | ||
} | ||
|
||
if ( ! preg_match( self::SLUG_REGEX, $pattern_data['slug'] ) ) { | ||
_doing_it_wrong( | ||
'register_block_patterns', | ||
esc_html( | ||
sprintf( | ||
/* translators: %1s: file name; %2s: slug value found. */ | ||
__( 'Could not register file "%1$s" as a block pattern (invalid slug "%2$s")', 'woo-gutenberg-products-block' ), | ||
$file, | ||
$pattern_data['slug'] | ||
) | ||
), | ||
'6.0.0' | ||
); | ||
continue; | ||
} | ||
|
||
if ( \WP_Block_Patterns_Registry::get_instance()->is_registered( $pattern_data['slug'] ) ) { | ||
continue; | ||
} | ||
|
||
// Title is a required property. | ||
if ( ! $pattern_data['title'] ) { | ||
_doing_it_wrong( | ||
'register_block_patterns', | ||
esc_html( | ||
sprintf( | ||
/* translators: %1s: file name; %2s: slug value found. */ | ||
__( 'Could not register file "%s" as a block pattern ("Title" field missing)', 'woo-gutenberg-products-block' ), | ||
$file | ||
) | ||
), | ||
'6.0.0' | ||
); | ||
continue; | ||
} | ||
|
||
// For properties of type array, parse data as comma-separated. | ||
foreach ( array( 'categories', 'keywords', 'blockTypes' ) as $property ) { | ||
if ( ! empty( $pattern_data[ $property ] ) ) { | ||
$pattern_data[ $property ] = array_filter( | ||
preg_split( | ||
self::COMMA_SEPARATED_REGEX, | ||
(string) $pattern_data[ $property ] | ||
) | ||
); | ||
} else { | ||
unset( $pattern_data[ $property ] ); | ||
} | ||
} | ||
|
||
// Parse properties of type int. | ||
foreach ( array( 'viewportWidth' ) as $property ) { | ||
if ( ! empty( $pattern_data[ $property ] ) ) { | ||
$pattern_data[ $property ] = (int) $pattern_data[ $property ]; | ||
} else { | ||
unset( $pattern_data[ $property ] ); | ||
} | ||
} | ||
|
||
// Parse properties of type bool. | ||
foreach ( array( 'inserter' ) as $property ) { | ||
if ( ! empty( $pattern_data[ $property ] ) ) { | ||
$pattern_data[ $property ] = in_array( | ||
strtolower( $pattern_data[ $property ] ), | ||
array( 'yes', 'true' ), | ||
true | ||
); | ||
} else { | ||
unset( $pattern_data[ $property ] ); | ||
} | ||
} | ||
|
||
// phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText, WordPress.WP.I18n.LowLevelTranslationFunction | ||
$pattern_data['title'] = translate_with_gettext_context( $pattern_data['title'], 'Pattern title', 'woo-gutenberg-products-block' ); | ||
if ( ! empty( $pattern_data['description'] ) ) { | ||
// phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText, WordPress.WP.I18n.LowLevelTranslationFunction | ||
$pattern_data['description'] = translate_with_gettext_context( $pattern_data['description'], 'Pattern description', 'woo-gutenberg-products-block' ); | ||
} | ||
|
||
// The actual pattern content is the output of the file. | ||
ob_start(); | ||
include $file; | ||
$pattern_data['content'] = ob_get_clean(); | ||
if ( ! $pattern_data['content'] ) { | ||
continue; | ||
} | ||
|
||
foreach ( $pattern_data['categories'] as $key => $category ) { | ||
$category_slug = _wp_to_kebab_case( $category ); | ||
|
||
$pattern_data['categories'][ $key ] = $category_slug; | ||
|
||
register_block_pattern_category( | ||
$category_slug, | ||
// phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText | ||
array( 'label' => __( $category, 'woo-gutenberg-products-block' ) ) | ||
); | ||
} | ||
|
||
register_block_pattern( $pattern_data['slug'], $pattern_data ); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters