Skip to content

Instantly share code, notes, and snippets.

@roseg43
Created May 17, 2024 13:32
Show Gist options
  • Save roseg43/796db672aa8aab125fb69ddc6477ca07 to your computer and use it in GitHub Desktop.
Save roseg43/796db672aa8aab125fb69ddc6477ca07 to your computer and use it in GitHub Desktop.
A helper method for conditionally registering WordPress Block Styles based on content type.
import { subscribe, select } from '@wordpress/data';
import { registerBlockStyle } from '@wordpress/blocks';
/**
* @typedef {Object} BlockStyle
* @description The block style options, or an array of styles to register. Equivalent to `wp.blocks.registerBlockStyle`
* @property {string} name The slug of the block style
* @property {string} label The label of the block style
*/
/**
* @typedef {Object} FiltersObj
* @description Allow and deny post type filters
* @property {array} filters.allow Array of content types to allow
* @property {array} filters.deny Array of content types to deny
*/
/**
* Wrapper around registerBlockStyle that registers a Block Style
* only for specific content types.
*
* @param {string} blockName The block slug to add the style to.
* @param {BlockStyle|Array<BlockStyle>} styles The block style options, or an array of styles to register.
* @param {FiltersObj} filters Allow and deny post type filters
*/
export function registerBlockStyleByContentType( blockName, styles, filters ) {
const { allow, deny } = filters || {allow: false, deny: false};
const isAllowList = Array.isArray( allow );
// Subscribe to the post type
const unsubscribe = subscribe( () => {
const postType = select( 'core/editor' ).getCurrentPostType();
if ( !postType ) {
return;
}
// Once we have a post type, we don't need to be subbed to changes.
unsubscribe();
let isAllowed = !isAllowList;
if ( isAllowList ) {
isAllowed = allow.includes( postType );
} else if ( Array.isArray( deny ) && deny.includes( postType ) ) {
isAllowed = false;
}
if ( !isAllowed ) {
return;
}
// If passing an array of styles, register each one.
// Otherwise, just register the single style.
if ( Array.isArray( styles ) ) {
styles.forEach( style => registerBlockStyle( blockName, style ) );
} else {
registerBlockStyle( blockName, styles );
}
} );
}
/**
* Allows registering multiple block styles in a single function call,
* conditionally based on content type.
*
* @param {Array} blockStyles
* @param {string} blockStyles.blockName The block slug to add the style to. Equivalent to `wp.blocks.registerBlockType`
* @param {BlockStyle} blockStyles.styles The block style options. Equivalent to `wp.blocks.registerBlockStyle`
* @param {FiltersObj} blockStyles.filters Allow and deny post type filters
*
* @example ```
* registerBlockStylesByContentTypeArray([
* {
* blockName: 'core/heading',
* styles: {
* name: 'chevron-right',
* label: 'Chevron',
* },
* filters: {
* allow: [ 'page', 'msr-focus-area-post' ],
* deny: [],
* }
* }
* ]);
* ```
*/
export function registerBlockStylesByContentTypeArray( blockStyles ) {
blockStyles.forEach( ( { blockName, styles, filters } ) => {
registerBlockStyleByContentType( blockName, styles, filters );
} );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment