WordPress Gutenberg能否多选区块样式实现CSS类拼接?
问题结论
WordPress 区块编辑器原生的wp.blocks.registerBlockStyle接口本身为单选互斥设计:选中新样式时会自动移除同区块下其他通过该接口注册的样式类名,不存在原生配置项支持多选。要实现多样式类名拼接的效果,可以采用以下两种实现方案。
方案一:自定义属性+侧边栏多选控件(官方推荐,兼容性最好)
这个方案通过Gutenberg提供的官方过滤器扩展区块能力,不依赖编辑器DOM结构,版本兼容性最强,是生产环境首选方案,实现步骤如下:
- 移除原有
registerBlockStyle注册代码,避免原生单选样式面板和自定义多选面板冲突 - 通过过滤器给
core/image区块追加数组类型的自定义属性,存储用户选中的多个样式值 - 在区块侧边栏的样式面板区域添加多选框控件,供用户勾选需要的样式
- 通过内容保存过滤器,把用户选中的样式类名自动拼接到区块的class属性中
对应实现代码如下,直接放到你主题的editor.js中即可:
// 1. 给核心图片区块注册多样式存储属性 wp.hooks.addFilter( 'blocks.registerBlockType', 'my-theme/image-multi-style-attr', (settings, blockName) => { if (blockName !== 'core/image') return settings; return { ...settings, attributes: { ...settings.attributes, customImageStyles: { type: 'array', default: [] } } } } ); // 2. 在区块侧边栏注入多样式选择面板 wp.hooks.addFilter( 'editor.BlockEdit', 'my-theme/image-multi-style-control', wp.compose.createHigherOrderComponent((BlockEdit) => { return (props) => { if (props.name !== 'core/image') return wp.element.createElement(BlockEdit, props); const { attributes, setAttributes } = props; const { customImageStyles } = attributes; // 可选择的样式项,类名前缀和原生样式保持一致,用is-style-开头 const styleList = [ { label: 'Rounded', value: 'is-style-rounded' }, { label: 'Desktop', value: 'is-style-desktop' }, { label: 'Mobile', value: 'is-style-mobile' } ]; // 切换样式选中状态 const toggleStyleSelect = (styleValue) => { setAttributes({ customImageStyles: customImageStyles.includes(styleValue) ? customImageStyles.filter(item => item !== styleValue) : [...customImageStyles, styleValue] }); }; return wp.element.createElement( wp.element.Fragment, null, wp.element.createElement(BlockEdit, props), wp.element.createElement( wp.blockEditor.InspectorControls, { group: 'styles' }, wp.element.createElement( 'div', { style: { padding: '0 16px 16px' } }, wp.element.createElement('p', { style: { fontWeight: 500, marginTop: 0 } }, '图片样式(可多选)'), styleList.map(styleItem => ( wp.element.createElement(wp.components.CheckboxControl, { key: styleItem.value, label: styleItem.label, checked: customImageStyles.includes(styleItem.value), onChange: () => toggleStyleSelect(styleItem.value) }) )) ) ) ); }; }, 'withImageMultiStyleControl') ); // 3. 保存内容时自动拼接选中的样式类名 wp.hooks.addFilter( 'blocks.getSaveContent.extraProps', 'my-theme/image-multi-style-class', (extraProps, blockType, attributes) => { if (blockType.name !== 'core/image') return extraProps; const { customImageStyles } = attributes; if (!customImageStyles.length) return extraProps; const originClass = extraProps.className || ''; extraProps.className = [originClass, ...customImageStyles].filter(Boolean).join(' '); return extraProps; } );
注:如果你的主题构建流程支持JSX编译,可以把
wp.element.createElement写法替换成常规JSX标签写法,代码可读性会更高。
代码生效后,用户同时勾选Rounded和Mobile时,前端渲染的图片标签会自动带上is-style-rounded is-style-mobile两个类名,你提前写好对应类的CSS规则就能正常生效,用户不选任何自定义样式时就是默认效果。
方案二:DOM层Hack实现(临时方案,不推荐生产使用)
如果不想扩展区块属性,也可以通过JS拦截原生样式按钮的点击事件,移除默认的单选互斥逻辑,手动维护类名的增删。但这个方案依赖Gutenberg编辑器的DOM结构,后续版本更新很容易失效,仅适合临时快速测试使用,不建议在正式站点部署。
内容的提问来源于stack exchange,提问作者Joe Shockey
相关产品推荐
相关产品推荐

