如何为ACF InnerBlocks内部区块添加自定义class属性且不限制数量
可行实现方案
方案1:使用render_block官方过滤器追加类名(最推荐)
这是完全不侵入原有InnerBlocks配置、也不限制区块数量的最优方案,直接在区块渲染到前端时自动注入自定义类名,属于WordPress官方提供的挂钩方式,性能和可维护性远高于自行对整页内容做str_replace匹配:
// 代码添加到主题functions.php或自定义插件主文件即可 add_filter( 'render_block', function( $block_content, $block ) { // 替换此处的'acf/your-custom-block'为你自己注册ACF区块时设置的唯一slug // 仅匹配你自定义ACF区块下的子区块,避免全局污染其他位置的标题、段落 if ( isset( $block['parent'] ) && in_array( 'acf/your-custom-block', (array)$block['parent'] ) ) { // 给标题区块追加自定义类 if ( $block['blockName'] === 'core/heading' ) { // 兼容已有class属性的情况,不会覆盖原有类 if ( preg_match( '/<h([1-6])(\s+[^>]*?)>/i', $block_content, $matches ) ) { if ( strpos( $matches[2], 'class=' ) !== false ) { $new_attr = str_replace( 'class="', 'class="block__heading ', $matches[2] ); } else { $new_attr = $matches[2] . ' class="block__heading"'; } return str_replace( $matches[0], "<h{$matches[1]}{$new_attr}>", $block_content ); } } // 给段落区块追加自定义类 if ( $block['blockName'] === 'core/paragraph' ) { if ( preg_match( '/<p(\s+[^>]*?)>/i', $block_content, $matches ) ) { if ( strpos( $matches[1], 'class=' ) !== false ) { $new_attr = str_replace( 'class="', 'class="block__paragraph ', $matches[1] ); } else { $new_attr = $matches[1] . ' class="block__paragraph"'; } return str_replace( $matches[0], "<p{$new_attr}>", $block_content ); } } } return $block_content; }, 10, 2 );
方案2:编辑器端JS钩子自动注入类名(同步编辑器预览效果)
如果需要在编辑器中添加区块时就自动带上自定义类,和前端渲染效果保持一致,可以额外增加一段编辑器侧的JS逻辑:
// 代码需通过enqueue_block_editor_assets钩子挂载到区块编辑器 wp.hooks.addFilter( 'blocks.getSaveContent.extraProps', 'your-custom-namespace/add-inner-block-class', ( props, blockType ) => { const allowedBlocks = [ 'core/heading', 'core/paragraph' ]; const selectedBlock = wp.data.select( 'core/block-editor' ).getSelectedBlock(); if ( !selectedBlock || !allowedBlocks.includes( blockType.name ) ) return props; const parentBlock = wp.data.select( 'core/block-editor' ).getBlock( selectedBlock.parentClientId ); // 替换此处的'acf/your-custom-block'为你的ACF区块slug if ( parentBlock?.name !== 'acf/your-custom-block' ) return props; const customClass = blockType.name === 'core/heading' ? 'block__heading' : 'block__paragraph'; return { ...props, className: `${ props.className || '' } ${ customClass }`.trim() }; } );
补充说明:你提到的template方案实际上并不会强制限定区块数量,只要不将
templateLock设置为all或insert,用户依然可以自由添加额外的允许区块,template只是用来预置默认的区块结构而已,不需要预置内容的话完全可以留空template配置,不会影响正常使用。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

