自定义Gutenberg块内容变更检测:save_post时如何仅通知/检查?
如何在Gutenberg自定义块内容变化时触发更新检查/通知?
完全可行,你可以通过前端监听块属性变化、结合文章保存钩子,或者后端对比内容的方式实现,以下是具体方案:
前端实现(编辑器内触发)
1. 追踪块属性变化
在自定义块的Edit组件中,通过useEffect监听属性变动,记录块是否发生修改:
import { useEffect, useState } from '@wordpress/element'; import { useBlockProps } from '@wordpress/block-editor'; export default function Edit({ attributes, setAttributes }) { const blockProps = useBlockProps(); const [initialAttrs, setInitialAttrs] = useState({ ...attributes }); const [blockChanged, setBlockChanged] = useState(false); // 每次属性更新时对比初始值 useEffect(() => { const isChanged = Object.keys(initialAttrs).some(key => initialAttrs[key] !== attributes[key] ); setBlockChanged(isChanged); }, [attributes, initialAttrs]); // 编辑组件的其他逻辑... return <div {...blockProps}>你的块编辑内容</div>; }
2. 拦截文章保存动作触发检查
借助WordPress的数据钩子,在保存文章前检查当前块是否有变化,触发通知或自定义逻辑:
import { useEffect } from '@wordpress/element'; import { useDispatch, useSelect } from '@wordpress/data'; export default function Edit({ attributes, clientId }) { const { savePost } = useDispatch('core/editor'); const { getBlock } = useSelect('core/block-editor'); const [initialAttrs] = useState({ ...attributes }); useEffect(() => { // 保存原始的savePost方法 const originalSave = savePost; // 自定义保存逻辑 const customSave = async () => { const currentBlock = getBlock(clientId); if (!currentBlock) return originalSave(); // 对比初始属性和当前属性 const isChanged = Object.keys(initialAttrs).some(key => initialAttrs[key] !== currentBlock.attributes[key] ); if (isChanged) { // 这里替换成你的通知/检查逻辑,比如弹窗提示、调用API等 console.log('自定义块内容已更新'); } // 执行原始保存动作 await originalSave(); }; // 替换savePost方法 savePost(customSave); // 组件卸载时恢复原始方法 return () => savePost(originalSave); }, [savePost, getBlock, clientId, initialAttrs]); // 编辑组件的其余代码... }
后端实现(保存后验证)
如果需要在后端完成检查或通知,可以通过save_post钩子对比文章更新前后的块内容:
add_action('save_post', 'check_custom_block_modification', 10, 3); function check_custom_block_modification($post_id, $post, $update) { // 跳过自动保存和新增文章,只处理更新 if (!$update || wp_is_post_autosave($post_id) || wp_is_post_revision($post_id)) { return; } // 获取更新前后的文章内容 $old_content = get_post_field('post_content', $post_id, 'raw'); $new_content = $post->post_content; // 解析块结构 $old_blocks = parse_blocks($old_content); $new_blocks = parse_blocks($new_content); // 递归查找自定义块的属性 $extract_block_attrs = function($blocks) use (&$extract_block_attrs) { foreach ($blocks as $block) { if ($block['blockName'] === 'your-namespace/your-custom-block') { return $block['attrs']; } if (!empty($block['innerBlocks'])) { $inner_result = $extract_block_attrs($block['innerBlocks']); if ($inner_result) return $inner_result; } } return null; }; $old_attrs = $extract_block_attrs($old_blocks); $new_attrs = $extract_block_attrs($new_blocks); // 对比属性是否变化 if ($old_attrs !== $new_attrs) { // 触发你的通知逻辑:比如发送邮件、写入日志、调用外部API等 error_log('自定义块已修改,文章ID: ' . $post_id); } }
内容的提问来源于stack exchange,提问作者Renan Bessa
相关产品推荐
相关产品推荐

