Skip to content

Latest commit

 

History

History
215 lines (196 loc) · 7.52 KB

File metadata and controls

215 lines (196 loc) · 7.52 KB

Step 12: Client-side filters

1. Setup

  1. In the /assets/js folder, create a new file named /client-side-filters.js.
  2. At the top of the JavaScript file, add the following:
const { addFilter } = wp.hooks;
const { select } = wp.data;
  1. In the functions.php file, use the hook enqueue_block_editor_assets to enqueue the JavaScript file using the following code:
/**
 * Enqueue client-side filters used for Editor curation.
 */
function wpu_enqueue_client_side_filters() {
	wp_enqueue_script( 
		'wpu-enqueue-client-side-filters', 
		get_template_directory_uri() . '/assets/js/client-side-filters.js', 
		array(),
		wp_get_theme()->get( 'Version' ),
		true
	);
}
add_action( 'enqueue_block_editor_assets', 'wpu_enqueue_client_side_filters' );

2. Modify default block controls

  1. Navigate to the Editor of any post or page. Add a Paragraph and a Heading block. Notice that the default typography controls are different.
  2. In the /client-side-filters.js, use the blocks.registerBlockType filter to standardize the default typography controls for all blocks that support typography. Use the following code:
/**
 * Modifies the default typography settings for blocks with typography support.
 * 
 * @see https://nickdiego.com/how-to-modify-block-supports-using-client-side-filters/
 * 
 * @param {Object} settings - The original block settings.
 * 
 * @returns {Object} The modified block settings with updated typography defaults.
 */
function modifyTypographyDefaults( settings ) {

	// Only apply to blocks with typography support.
	if ( settings?.supports?.typography ) {
		return Object.assign( {}, settings, {
			supports: Object.assign( settings.supports, {
				typography: Object.assign( settings.supports.typography, {
					__experimentalDefaultControls: {
						fontAppearance: true,
						fontSize: true
					}
				} ),
			} ),
		} );
	}

	return settings;
}

addFilter(
	'blocks.registerBlockType',
	'modify-block-supports/modify-typography-defaults',
	modifyTypographyDefaults,
);

3. Restrict border controls for specific users

  1. In the /client-side-filters.js, use the blockEditor.useSetting.before filter to disable border control for non-Administrators on posts. Use the following code:
/**
 * If the user doesn't have permission to update settings (Editors,
 * Authors, etc.), disable the specified block settings when editing
 * the specified post types.
 * 
 * @see https://developer.wordpress.org/news/2023/05/curating-the-editor-experience-with-client-side-filters/
 *
 * @param {any}    settingValue The current value of the block setting.
 * @param {string} settingName  The name of the block setting to modify.
 * @param {string} clientId     The unique identifier for the block in the client.
 * @param {string} blockName    The name of the block type.
 * 
 * @return {any} Returns the modified setting value or the original setting value.
 */
function restrictBlockSettingsByUserPermissionsAndPostType(
	settingValue,
	settingName,
	clientId,
	blockName
) {
	const { canUser } = select( 'core' );
	const { getCurrentPostType } = select( 'core/editor' );

	// Check user permissions and get the current post type.
	const canUserUpdateSettings = canUser( 'update', 'settings' );
	const currentPostType = getCurrentPostType();

	// Disable block settings on these post types.
	const disabledPostTypes = [
		'post',
		// Add additional post types here.
	];

	// Disable these block settings.
	const disabledBlockSettings = [
		'border.color',
		'border.radius',
		'border.style',
		'border.width',
		// Add additional block settings here.
	];

	if (
		! canUserUpdateSettings &&
		disabledPostTypes.includes( currentPostType ) &&
		disabledBlockSettings.includes( settingName )
	) {
		return false;
	}

	return settingValue;
}

addFilter(
	'blockEditor.useSetting.before',
	'editor-curation-examples/useSetting.before/user-permissions-and-post-type',
	restrictBlockSettingsByUserPermissionsAndPostType
);
  1. Switch to the Editor user (created earlier) and confirm that border control is not available for any block when editing posts.
  2. Confirm it is available when editing other post types.

3. Restrict block settings based on context

  1. Navigate to and edit the "Page Elements" page.
  2. Click on the Button that is located in the Cover block and confirm that all colors are available for both text and background.
  3. In the /client-side-filters.js, use the blockEditor.useSetting.before filter to disable all custom colors/gradients and restrict the color palette to base, contrast, and primary, whenever a Button block is placed inside of a Cover block. Use the following code:
/**
 * If a 'core/button' block is within a 'core/cover' block, update the
 * color palette to only include 'Base', 'Contrast', or 'Primary'. 
 * Also disable custom colors and gradients.
 * 
 * @see https://developer.wordpress.org/news/2023/05/curating-the-editor-experience-with-client-side-filters/
 *
 * @param {any}    settingValue The current value of the block setting.
 * @param {string} settingName  The name of the block setting to modify.
 * @param {string} clientId     The unique identifier for the block in the client.
 * @param {string} blockName    The name of the block type.
 * 
 * @return {any} Returns the modified setting value or the original setting value.
 */
function restrictButtonBlockSettingsByLocation(
	settingValue,
	settingName,
	clientId,
	blockName
) {
	if ( blockName === 'core/button' ) {
		const { getBlockParents, getBlockName } = select( 'core/block-editor' );

		// Get the block's parents and see if one is a 'core/cover' block.
		const blockParents = getBlockParents( clientId, true );
		const inCover = blockParents.some(
			( parentId ) => getBlockName( parentId ) === 'core/cover'
		);

		// Modify these block settings.
		const modifiedBlockSettings = {
			'color.custom': false,
			'color.customGradient': false,
			'color.defaultGradients': false,
			'color.defaultPalette': false,
			'color.gradients.theme': [],
			'color.palette.theme': [
				{
					color: '#ffffff',
					name: 'Base',
					slug: 'base',
				},
				{
					color: '#000000',
					name: 'Contrast',
					slug: 'contrast',
				},
                {
					color: '#3858e9',
					name: 'Primary',
					slug: 'primary',
				},
			],
			// Add additional block settings here.
		};

		if ( inCover && modifiedBlockSettings.hasOwnProperty( settingName ) ) {
			return modifiedBlockSettings[ settingName ];
		}
	}

	return settingValue;
}

addFilter(
	'blockEditor.useSetting.before',
	'editor-curation-examples/useSetting.before/button-location',
	restrictButtonBlockSettingsByLocation
);
  1. Refresh the Page Elements page and confirm that the color options are now restricted for the Button in the Cover block.
  2. Click on the Button block inside of the Media & Text block (below the Cover) and confirm that all color options are available.

Resources


← Previous