From a01a119584316d720e09db26d2de83b2f283ab2b Mon Sep 17 00:00:00 2001 From: Justin Frydman Date: Fri, 18 Mar 2022 16:18:05 -0600 Subject: [PATCH 1/5] Add block template page filtering backend --- .../Blocks/BlockPageTemplateFilterTest.php | 36 +++++++++++++++++ .../core/src/Assets/Admin/JS_Config.php | 6 ++- .../src/Blocks/Block_Page_Template_Filter.php | 40 +++++++++++++++++++ .../core/src/Blocks/Blocks_Definer.php | 23 +++++++++-- .../core/src/Blocks/Blocks_Subscriber.php | 10 ++++- 5 files changed, 108 insertions(+), 7 deletions(-) create mode 100644 dev/tests/tests/unit/Tribe/Project/Blocks/BlockPageTemplateFilterTest.php create mode 100644 wp-content/plugins/core/src/Blocks/Block_Page_Template_Filter.php diff --git a/dev/tests/tests/unit/Tribe/Project/Blocks/BlockPageTemplateFilterTest.php b/dev/tests/tests/unit/Tribe/Project/Blocks/BlockPageTemplateFilterTest.php new file mode 100644 index 000000000..6b864a3b3 --- /dev/null +++ b/dev/tests/tests/unit/Tribe/Project/Blocks/BlockPageTemplateFilterTest.php @@ -0,0 +1,36 @@ + [ + 'block_one', + 'block_two', + ], + 'page-templates/custom-template-two.php' => [ + 'block_three', + 'block_four', + ], + ]; + + $filter = new Block_Page_Template_Filter( $block_list ); + $list = $filter->get_block_list(); + + $this->assertCount(2, $list ); + + $this->assertSame( [ + 'acf/block_one', + 'acf/block_two', + ], $list['page-templates/custom-template-one.php'] ); + + $this->assertSame( [ + 'acf/block_three', + 'acf/block_four', + ], $list['page-templates/custom-template-two.php'] ); + } + +} diff --git a/wp-content/plugins/core/src/Assets/Admin/JS_Config.php b/wp-content/plugins/core/src/Assets/Admin/JS_Config.php index cf64420be..67bf0f98f 100644 --- a/wp-content/plugins/core/src/Assets/Admin/JS_Config.php +++ b/wp-content/plugins/core/src/Assets/Admin/JS_Config.php @@ -12,8 +12,10 @@ class JS_Config { public function get_data(): array { if ( ! isset( $this->data ) ) { $this->data = [ - 'images_url' => trailingslashit( get_stylesheet_directory_uri() ) . 'assets/img/admin/', - 'block_denylist' => (array) apply_filters( 'tribe/project/blocks/denylist', [] ), + 'images_url' => trailingslashit( get_stylesheet_directory_uri() ) . 'assets/img/admin/', + 'block_denylist' => (array) apply_filters( 'tribe/project/blocks/denylist', [] ), + 'block_page_template_filter' => (array) apply_filters( 'tribe/project/blocks/page_template_filter', [] ), + ]; $this->data = (array) apply_filters( 'core_admin_js_config', $this->data ); diff --git a/wp-content/plugins/core/src/Blocks/Block_Page_Template_Filter.php b/wp-content/plugins/core/src/Blocks/Block_Page_Template_Filter.php new file mode 100644 index 000000000..7c713cd7c --- /dev/null +++ b/wp-content/plugins/core/src/Blocks/Block_Page_Template_Filter.php @@ -0,0 +1,40 @@ + + */ + protected array $block_list; + + public function __construct( array $block_list = [] ) { + $this->block_list = $block_list; + $this->prefix_blocks(); + } + + /** + * @filter tribe/project/blocks/page_template_filter + * + * @return array + */ + public function get_block_list(): array { + return $this->block_list; + } + + /** + * Prefix all block names with "acf/" + * + * @return void + */ + protected function prefix_blocks(): void { + array_walk_recursive( $this->block_list, static fn ( &$name ) => + $name = sprintf( 'acf/%s', $name ) + ); + } + +} diff --git a/wp-content/plugins/core/src/Blocks/Blocks_Definer.php b/wp-content/plugins/core/src/Blocks/Blocks_Definer.php index c27906616..a95032abf 100644 --- a/wp-content/plugins/core/src/Blocks/Blocks_Definer.php +++ b/wp-content/plugins/core/src/Blocks/Blocks_Definer.php @@ -32,7 +32,7 @@ class Blocks_Definer implements Definer_Interface { public function define(): array { return [ - self::TYPES => DI\add( [ + self::TYPES => DI\add( [ DI\get( Accordion::class ), DI\get( Buttons::class ), DI\get( Card_Grid::class ), @@ -60,7 +60,7 @@ public function define(): array { * * @see: https://developer.wordpress.org/block-editor/reference-guides/filters/block-filters/#using-a-deny-list */ - self::DENY_LIST => [ + self::DENY_LIST => [ 'core/archives', 'core/button', 'core/buttons', @@ -90,7 +90,7 @@ public function define(): array { * * TODO: Create a proper thumbnail of the style for the block editor: http://p.tri.be/dmsAwK */ - self::STYLES => DI\add( [ + self::STYLES => DI\add( [ DI\factory( static function () { return new Block_Style_Override( [ 'core/paragraph' ], [ [ @@ -113,7 +113,22 @@ public function define(): array { } ), ] ), - Block_Deny_List::class => DI\autowire()->constructor( DI\get( self::DENY_LIST ) ), + Block_Deny_List::class => DI\autowire()->constructor( DI\get( self::DENY_LIST ) ), + + /** + * Limit certain blocks to being available only on certain page templates. + * + * key: The page template slug. + * values: A list of block names that will only appear when that page template is selected. + * + * @see get_page_template_slug() + */ + Block_Page_Template_Filter::class => DI\autowire() + ->constructor( [ + /*'page-templates/page-template-name.php' => [ + Block_Type::NAME, + ],*/ + ] ), ]; } diff --git a/wp-content/plugins/core/src/Blocks/Blocks_Subscriber.php b/wp-content/plugins/core/src/Blocks/Blocks_Subscriber.php index 1428dff02..a3d749881 100644 --- a/wp-content/plugins/core/src/Blocks/Blocks_Subscriber.php +++ b/wp-content/plugins/core/src/Blocks/Blocks_Subscriber.php @@ -20,12 +20,20 @@ public function register(): void { }, 10, 4 ); /** - * Adds the deny list to the JS_Config class. + * Adds the Deny List to the JS_Config class. */ add_filter( 'tribe/project/blocks/denylist', function ( array $types ): array { return $this->container->get( Block_Deny_List::class )->filter_block_denylist( $types ); }, 10, 1 ); + /** + * Limit certain blocks to being available only on certain page templates + * by adding a global object list via the JS_Config class. + */ + add_filter( 'tribe/project/blocks/page_template_filter', function (): array { + return $this->container->get( Block_Page_Template_Filter::class )->get_block_list(); + }, 10, 1 ); + add_action( 'after_setup_theme', function (): void { $this->container->get( Theme_Support::class )->register_theme_supports(); From bd8a713d04ba4391cc4b4fe97997b6d1011e3258 Mon Sep 17 00:00:00 2001 From: Justin Frydman Date: Fri, 18 Mar 2022 16:18:47 -0600 Subject: [PATCH 2/5] Add block template page filtering frontend for editor --- .../assets/js/src/admin/config/wp-settings.js | 1 + .../core/assets/js/src/admin/editor/index.js | 2 + .../editor/page-template-block-filter.js | 99 +++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 wp-content/themes/core/assets/js/src/admin/editor/page-template-block-filter.js diff --git a/wp-content/themes/core/assets/js/src/admin/config/wp-settings.js b/wp-content/themes/core/assets/js/src/admin/config/wp-settings.js index 053d314eb..8a29ea7ba 100644 --- a/wp-content/themes/core/assets/js/src/admin/config/wp-settings.js +++ b/wp-content/themes/core/assets/js/src/admin/config/wp-settings.js @@ -2,3 +2,4 @@ const wp = window.modern_tribe_admin_config || {}; export const HMR_DEV = wp.hmr_dev || 0; export const BLOCK_DENYLIST = wp.block_denylist || []; +export const BLOCK_PAGE_TEMPLATE_FILTER = wp.block_page_template_filter || []; diff --git a/wp-content/themes/core/assets/js/src/admin/editor/index.js b/wp-content/themes/core/assets/js/src/admin/editor/index.js index 1231ddb78..abeff1cd5 100644 --- a/wp-content/themes/core/assets/js/src/admin/editor/index.js +++ b/wp-content/themes/core/assets/js/src/admin/editor/index.js @@ -2,6 +2,7 @@ import hooks from './hooks'; import types from './types'; import * as tools from 'utils/tools'; import denyBlocks from './deny-blocks'; +import pageTemplateBlockFilter from './page-template-block-filter'; /** * @function init @@ -12,6 +13,7 @@ const init = () => { hooks(); types(); denyBlocks(); + pageTemplateBlockFilter(); if ( tools.getNodes( '#editor.block-editor__container', false, document, true )[ 0 ] ) { import( './preview' /* webpackChunkName:"editor-preview" */ ).then( ( module ) => { diff --git a/wp-content/themes/core/assets/js/src/admin/editor/page-template-block-filter.js b/wp-content/themes/core/assets/js/src/admin/editor/page-template-block-filter.js new file mode 100644 index 000000000..aebbf4e86 --- /dev/null +++ b/wp-content/themes/core/assets/js/src/admin/editor/page-template-block-filter.js @@ -0,0 +1,99 @@ +import { select, subscribe } from '@wordpress/data'; +import { BLOCK_PAGE_TEMPLATE_FILTER } from '../config/wp-settings'; +import { getBlockTypes, unregisterBlockType, registerBlockType } from '@wordpress/blocks'; + +const state = { + template: 'default', // The default WordPress template + deletedBlockMap: new Map(), // Stores the state of blocks that have been unregistered. +}; + +const { isTyping } = select( 'core/block-editor' ); + +/** + * Registers a block if it's been unregistered. + * + * @param {string} block - The block name. + */ +const restoreBlock = ( block ) => { + if ( ! state.deletedBlockMap.has( block ) ) { + return; + } + + registerBlockType( block, state.deletedBlockMap.get( block ) ); + state.deletedBlockMap.delete( block ); +}; + +const updateAvailableBlocks = () => { + const templateMap = new Map( Object.entries( BLOCK_PAGE_TEMPLATE_FILTER ) ); + const blockTypeMap = new Map( getBlockTypes().map( block => [ block.name, block ] ) ); + + if ( templateMap.size < 1 ) { + return false; + } + + if ( templateMap.has( state.template ) ) { + const blocks = templateMap.get( state.template ); + const restored = []; + + for ( const block of blocks ) { + restoreBlock( block ); + restored.push( block ); + } + + // Remove the blocks assigned to this template, so they aren't unregistered. + templateMap.delete( state.template ); + + if ( restored.length ) { + console.info( `SquareOne Admin: Restored blocks: "${ restored.join( ',' ) }" for template: ${ state.template }` ); + } + } + + // Unregister all page template blocks that aren't for the current page template. + const removedBlocks = []; + + templateMap.forEach( blocks => { + for ( const block of blocks ) { + if ( blockTypeMap.has( block ) && ! state.deletedBlockMap.get( block ) ) { + state.deletedBlockMap.set( block, blockTypeMap.get( block ) ); + unregisterBlockType( block ); + removedBlocks.push( block ); + } + } + } ); + + if ( removedBlocks.length ) { + console.info( `SquareOne Admin: Removed blocks: "${ removedBlocks.join( ',' ) }"` ); + } +}; + +/** + * Subscribes an event listener to determine if we need + * to adjust the available blocks based on if the page template changed. + */ +const pageTemplateBlockFilter = () => { + subscribe( () => { + if ( isTyping() === true ) { + return false; + } + + const newTemplate = select( 'core/editor' ).getEditedPostAttribute( 'template' ); + + if ( newTemplate !== undefined && newTemplate !== state.template ) { + state.template = newTemplate; + updateAvailableBlocks(); + } + } ); +}; + +/** + * @function init + * @description Initialize module + */ + +const init = () => { + // Set the initial block state + updateAvailableBlocks(); + pageTemplateBlockFilter(); +}; + +export default init; From 3b4c32af43b435dd4b39401155be2b8818d73930 Mon Sep 17 00:00:00 2001 From: Justin Frydman Date: Fri, 18 Mar 2022 16:19:06 -0600 Subject: [PATCH 3/5] gulp dist --- wp-content/themes/core/components/card/js/card.js | 1 - 1 file changed, 1 deletion(-) diff --git a/wp-content/themes/core/components/card/js/card.js b/wp-content/themes/core/components/card/js/card.js index 292b29aea..2dd0be551 100644 --- a/wp-content/themes/core/components/card/js/card.js +++ b/wp-content/themes/core/components/card/js/card.js @@ -9,7 +9,6 @@ import delegate from 'delegate'; import * as tools from 'utils/tools'; - /* Maximum amount of time between mousedown & mouseup to be considered a true click */ const MOUSEUP_THRESHOLD = 200; From ef25ee118683cc654d733d98b5d5d91684e0f5d9 Mon Sep 17 00:00:00 2001 From: Justin Frydman Date: Fri, 18 Mar 2022 16:19:21 -0600 Subject: [PATCH 4/5] Update changelog.md --- changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.md b/changelog.md index 780ad3bc7..b00c8a5fc 100644 --- a/changelog.md +++ b/changelog.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. ## 2022.03 +* Added: Block Page Template Filter: Allow certain blocks to only be chosen when using a specific page template. * Changed: Replaced `msawicki/acf-menu-chooser` with a forked https://github.com/moderntribe/acf-menu-chooser that includes security fixes and is also added to packagist. * Updated: ACF (5.12), Tribe Libs (3.4.10), Redirection (5.2.3), Yoast (18.2), TEC (5.14.0.4) * Updated: Aligns accordion component with WAI-ARIA standard From 38be32ca337ae94a7d340c2030a07a35dad315da Mon Sep 17 00:00:00 2001 From: Justin Frydman Date: Fri, 18 Mar 2022 16:26:52 -0600 Subject: [PATCH 5/5] Fix formatting --- .../unit/Tribe/Project/Blocks/BlockPageTemplateFilterTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/tests/unit/Tribe/Project/Blocks/BlockPageTemplateFilterTest.php b/dev/tests/tests/unit/Tribe/Project/Blocks/BlockPageTemplateFilterTest.php index 6b864a3b3..1e8ca097c 100644 --- a/dev/tests/tests/unit/Tribe/Project/Blocks/BlockPageTemplateFilterTest.php +++ b/dev/tests/tests/unit/Tribe/Project/Blocks/BlockPageTemplateFilterTest.php @@ -1,4 +1,4 @@ -get_block_list(); - $this->assertCount(2, $list ); + $this->assertCount( 2, $list ); $this->assertSame( [ 'acf/block_one',