WordPress动态自定义区块开发求助:获取属性与执行短码
解决方案与优化建议
一、服务器端获取属性并执行短码的实现步骤
1. 配置block.json的渲染路径
确保你的block.json中指定服务器端渲染的PHP文件路径,添加或修改render字段:
"render": "render.php", "editorScript": "file:./index.js", // 其他已有配置...
2. 编写服务器端渲染逻辑(render.php)
在render.php中直接获取区块属性,执行短码并替换占位符:
<?php /** * 服务器端渲染动态区块 */ // 获取区块属性 $attributes = $block['attributes'] ?? []; $shortcode = $attributes['apiShortcode'] ?? ''; $rich_text_template = $attributes['text'] ?? ''; // 初始化渲染结果 $rendered_content = ''; if (!empty($shortcode) && !empty($rich_text_template)) { // 提取短码标签(去除[]) $shortcode_tag = trim(str_replace(['[', ']'], '', $shortcode)); if (shortcode_exists($shortcode_tag)) { // 直接调用短码函数获取数据数组(避免do_shortcode将数组转成字符串) $api_data = call_user_func($GLOBALS['shortcode_tags'][$shortcode_tag]); // 替换富文本中的占位符(假设占位符格式为{{key}}) foreach ($api_data as $key => $value) { $rich_text_template = str_replace("{{$key}}", esc_html($value), $rich_text_template); } $rendered_content = $rich_text_template; } else { // 短码不存在时的降级提示 $rendered_content = '<p>无效的API短码</p>'; } } else { // 字段未填写时的提示 $rendered_content = '<p>请填写API短码和富文本模板</p>'; } // 输出最终内容 echo $rendered_content; ?>
3. 带参数短码的处理方式
如果你的短码需要接收参数(如[my_api id="123"]),可以用do_shortcode解析执行,前提是短码函数返回数组而非直接输出:
// 示例:带参数的短码执行 $api_data = do_shortcode($shortcode);
二、当前方案的合理性与优化建议
合理性分析
你的方案完全符合需求且逻辑合理:
- 采用动态区块实现服务器端渲染,满足SEO对静态HTML内容的要求
- 通过短码封装API调用逻辑,与区块渲染解耦,复用已有的短码能力
- 每次文章渲染时重新执行短码,保证数据实时性
优化建议
短码安全校验
限制允许执行的短码白名单,避免恶意短码执行:$allowed_shortcodes = ['my_api_data', 'custom_api_shortcode']; if (in_array($shortcode_tag, $allowed_shortcodes) && shortcode_exists($shortcode_tag)) { // 执行短码逻辑 }API请求性能优化
根据数据更新频率添加短暂缓存,减少重复API请求(兼顾实时性与性能):$cache_key = 'block_api_data_' . md5($shortcode); $api_data = wp_cache_get($cache_key); if (!$api_data) { $api_data = call_user_func($GLOBALS['shortcode_tags'][$shortcode_tag]); wp_cache_set($cache_key, $api_data, '', 60); // 缓存60秒 }编辑器预览优化
在Edit组件中添加预览功能,让编辑者在后台直观看到占位符替换效果:export default function Edit({attributes, setAttributes }) { const setText = (val) => setAttributes({text:val}); const setShortCode = (val) => setAttributes({apiShortcode:val}); // 模拟预览数据(也可通过wp.apiFetch调用真实API) const previewData = { title: '示例标题', content: '示例内容' }; let previewContent = attributes.text || ''; Object.keys(previewData).forEach(key => { previewContent = previewContent.replace(`{{${key}}}`, previewData[key]); }); return ( <div { ...useBlockProps() }> <h3>动态数据区块</h3> <label>API短码:</label> <PlainText onChange={setShortCode} value={attributes.apiShortcode} placeholder="例如:[my_api_data]"/> <label>富文本模板:</label> <RichText onChange={setText} value={attributes.text} placeholder="输入带占位符的富文本,例如:{{title}}"/> <div style={{ marginTop: '1rem', padding: '1rem', border: '1px solid #eee' }}> <h4>预览:</h4> <div dangerouslySetInnerHTML={{ __html: previewContent }} /> </div> </div> ); }属性默认值配置
在block.json中为属性添加默认值,避免空值报错:"attributes": { "apiShortcode": { "type": "string", "source": "text", "default": "" }, "text": { "type": "string", "source": "html", "default": "" } }
内容的提问来源于stack exchange,提问作者Christian
相关产品推荐
相关产品推荐

