15 KiB
电子邮件编辑器的区块注册
本指南解释了如何注册 WordPress 区块以支持在 WooCommerce 电子邮件编辑器中进行电子邮件渲染。电子邮件编辑器扩展了 WordPress 古腾堡区块,增加了电子邮件特定的渲染功能,允许区块生成与电子邮件客户端兼容的 HTML。
目录
概述
WooCommerce 邮件编辑器允许在邮件兼容的 HTML 中渲染 WordPress 区块。要使一个区块兼容邮件渲染,您需要:
- 启用邮件支持:在区块配置中设置
supports.email = true - 提供邮件渲染回调函数:该函数生成邮件兼容的 HTML
- 实现渲染逻辑:将区块内容转换为邮件友好的标记
邮件编辑器会自动检测支持邮件的区块,并使用其自定义的渲染回调函数,而不是默认的 WordPress 区块渲染。
区块配置
电子邮件支持属性
要表明区块支持电子邮件渲染,请在区块的 supports 配置中将 email 属性设置为 true:
$block_settings = array(
'name' => 'my-plugin/custom-block',
'title' => 'Custom Block',
'supports' => array(
'email' => true, // 启用电子邮件支持
// ... 其他支持
),
// ... 其他设置
);
邮件渲染回调
提供专门用于邮件渲染的自定义渲染回调:
$block_settings = array(
'name' => 'my-plugin/custom-block',
'render_email_callback' => array( $this, 'render_block_for_email' ),
// ... 其他设置
);
渲染回调应接受三个参数:
string $block_content- 原始区块 HTML 内容array $parsed_block- 包含属性的已解析区块数据Rendering_Context $rendering_context- 邮件渲染上下文
为邮件支持注册区块
方法一:使用 block_type_metadata_settings 过滤器
推荐的方法是在 block.json 文件或 JS 客户端注册中添加 supports.email。
另一种方法是使用 block_type_metadata_settings 过滤器在注册期间修改块设置:
/**
* 为自定义区块添加邮件支持。
*/
function add_email_support_to_blocks( $settings, $metadata ) {
// 应支持邮件渲染的区块列表
$email_supported_blocks = array(
'my-plugin/custom-block',
'my-plugin/another-block',
);
if ( in_array( $settings['name'], $email_supported_blocks, true ) ) {
// 启用邮件支持
$settings['supports']['email'] = true;
// 设置邮件渲染回调
$settings['render_email_callback'] = array(
'My_Plugin_Email_Renderer',
'render_block'
);
}
return $settings;
}
add_filter( 'block_type_metadata_settings', 'add_email_support_to_blocks', 10, 2 );
方法二:直接区块注册
您也可以直接注册支持邮件的区块:
/**
* 注册一个支持邮件的自定义区块。
*/
function register_custom_email_block() {
register_block_type( 'my-plugin/custom-block', array(
'title' => __( '自定义邮件区块', 'my-plugin' ),
'description' => __( '一个支持邮件的自定义区块。', 'my-plugin' ),
'category' => 'widgets',
'supports' => array(
'email' => true,
// ... 其他支持项
),
'attributes' => array(
'content' => array(
'type' => 'string',
'default' => '',
),
// ... 其他属性
),
'render_email_callback' => 'my_plugin_render_email_block',
) );
}
add_action( 'init', 'register_custom_email_block' );
创建邮件区块渲染器
抽象区块渲染器
对于更复杂的区块,您可以创建一个专用的渲染器类,该类继承自抽象区块渲染器:
<?php
namespace My_Plugin\Email\Renderer;
use Automattic\WooCommerce\EmailEditor\Integrations\Core\Renderer\Blocks\Abstract_Block_Renderer;
use Automattic\WooCommerce\EmailEditor\Engine\Renderer\ContentRenderer\Rendering_Context;
use Automattic\WooCommerce\EmailEditor\Integrations\Utils\Table_Wrapper_Helper;
/**
* 自定义区块的邮件渲染器。
*/
class Custom_Block_Renderer extends Abstract_Block_Renderer {
/**
* 为邮件渲染区块内容。
*
* @param string $block_content 区块内容。
* @param array $parsed_block 解析后的区块数据。
* @param Rendering_Context $rendering_context 渲染上下文。
* @return string
*/
public function render( string $block_content, array $parsed_block, Rendering_Context $rendering_context ): string {
$attributes = $parsed_block['attrs'] ?? array();
// 提取区块属性
$content = $attributes['content'] ?? '';
$text_color = $attributes['textColor'] ?? '';
$bg_color = $attributes['backgroundColor'] ?? '';
// 构建邮件兼容的 HTML
$styles = array();
if ( $text_color ) {
$styles[] = 'color: ' . esc_attr( sanitize_hex_color( $text_color ) );
}
if ( $bg_color ) {
$styles[] = 'background-color: ' . esc_attr( sanitize_hex_color( $bg_color ) );
}
$style_attr = ! empty( $styles ) ? ' style="' . implode( '; ', $styles ) . '"' : '';
$html = sprintf(
'<div%s>%s</div>',
$style_attr,
wp_kses_post( $content )
);
// 包装成邮件兼容的表格结构
return Table_Wrapper_Helper::render_table_wrapper( $html );
}
}
渲染上下文
Rendering_Context 对象提供对主题选项和其他渲染上下文的访问:
public function render( string $block_content, array $parsed_block, Rendering_Context $rendering_context ): string {
// 获取主题选项
$theme_settings = $rendering_context->get_theme_settings();
// 主题样式值
$theme_styles = $rendering_context->get_theme_styles();
// 获取主题 json
$theme_json = $rendering_context->get_theme_json();
// 在您的渲染逻辑中使用主题值
// ...
return $rendered_html;
}
表格包装助手
邮件客户端对 CSS 的支持有限,因此推荐使用基于表格的布局。Table_Wrapper_Helper 提供了用于创建邮件兼容表格结构的实用工具:
use Automattic\WooCommerce\EmailEditor\Integrations\Utils\Table_Wrapper_Helper;
// 基本表格包装
$html = Table_Wrapper_Helper::render_table_wrapper( $content );
// 带自定义属性的表格包装
$html = Table_Wrapper_Helper::render_table_wrapper(
$content,
array( 'width' => '100%' ), // 表格属性
array( 'style' => 'padding: 20px;' ), // 单元格属性
array(), // 行属性
true // 渲染单元格包装
);
完整示例
以下是一个注册支持邮件的自定义区块的完整示例:
<?php
/**
* Plugin Name: Custom Email Block
* Description: A newsletter signup block with email editor support
* Version: 1.0.0
* Author: Your Name
* Text Domain: my-plugin
*/
// 防止直接访问
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Custom Email Block Plugin
*/
class My_Custom_Email_Block {
public function __construct() {
add_action( 'init', array( $this, 'register_block' ) );
}
/**
* 使用直接注册方法注册自定义区块。
*/
public function register_block() {
// 加载区块 JavaScript
wp_register_script(
'newsletter-signup-block',
plugin_dir_url( __FILE__ ) . 'simple-block.js',
array( 'wp-blocks', 'wp-element', 'wp-block-editor', 'wp-components', 'wp-i18n' ),
'1.0.0'
);
// 注册区块类型
register_block_type( 'my-plugin/newsletter-signup', array(
'editor_script' => 'newsletter-signup-block',
'render_callback' => array( $this, 'render_frontend_block' ),
'render_email_callback' => array( $this, 'render_email_block' ),
) );
}
/**
* 为前端(非邮件上下文)渲染区块。
*/
public function render_frontend_block( $attributes ) {
$title = $attributes['title'] ?? 'Subscribe to our newsletter';
$description = $attributes['description'] ?? 'Get the latest updates delivered to your inbox.';
$button_text = $attributes['buttonText'] ?? 'Subscribe';
$button_url = $attributes['buttonUrl'] ?? '';
$html = '<div class="newsletter-signup-block">';
$html .= '<h3>' . esc_html( $title ) . '</h3>';
$html .= '<p>' . esc_html( $description ) . '</p>';
if ( $button_url && $button_text ) {
$html .= '<a href="' . esc_url( $button_url ) . '">' . esc_html( $button_text ) . '</a>';
}
$html .= '</div>';
return $html;
}
/**
* 为邮件渲染区块。
*/
public function render_email_block( $block_content, $parsed_block, $rendering_context ) {
$attributes = $parsed_block['attrs'] ?? array();
$title = $attributes['title'] ?? 'Default Email Title';
$description = $attributes['description'] ?? 'Default Email: Get the latest updates delivered to your inbox.';
$button_text = $attributes['buttonText'] ?? 'Default Email: Subscribe';
$button_url = $attributes['buttonUrl'] ?? '';
// 创建兼容电子邮件的 HTML
$html = '<table role="presentation" cellpadding="0" cellspacing="0" style="width: 100%;">
<tr>
<td style="padding: 20px; text-align: center; background-color: #f8f9fa;">
<h2 style="margin: 0 0 15px 0; font-family: Arial, sans-serif; color: #333;">' . esc_html( $title ) . '</h2>
<p style="margin: 0 0 20px 0; font-family: Arial, sans-serif; color: #666; line-height: 1.5;">' . esc_html( $description ) . '</p>';
if ( $button_url && $button_text ) {
$html .= '<a href="' . esc_url( $button_url ) . '" style="display: inline-block; padding: 12px 24px; background-color: #007cba; color: #ffffff; text-decoration: none; border-radius: 4px; font-family: Arial, sans-serif;">' . esc_html( $button_text ) . '</a>';
}
$html .= '</td>
</tr>
</table>';
return $html;
}
}
// 初始化插件
new My_Custom_Email_Block();
JS
/**
* 通讯区块的简单测试版本
*/
(function() {
console.log('Newsletter block JavaScript is loading...');
// 检查 WordPress 依赖项是否可用
if (typeof wp === 'undefined') {
console.error('WordPress dependencies not available');
return;
}
const { __ } = wp.i18n;
const { createElement } = wp.element;
const { registerBlockType } = wp.blocks;
const { useBlockProps } = wp.blockEditor;
console.log('Registering newsletter-signup block...');
registerBlockType('my-plugin/newsletter-signup', {
title: __('Newsletter Signup', 'my-plugin'),
icon: 'email-alt',
category: 'widgets',
description: __('A newsletter signup form for emails.', 'my-plugin'),
supports: {
email: true, // 电子邮件编辑器所需。
},
attributes: {
title: {
type: 'string',
default: 'Subscribe to our newsletter'
}
},
edit: function(props) {
const blockProps = useBlockProps();
return createElement(
'div',
blockProps,
createElement(
'div',
{
style: {
padding: '20px',
border: '1px solid #ccc',
textAlign: 'center'
}
},
createElement('h3', null, props.attributes.title),
createElement('p', null, 'Newsletter signup block - working!')
)
);
},
save: function() {
return null; // 服务器端渲染
}
});
console.log('Newsletter signup block registered successfully!');
})();
最佳实践
邮件兼容的 HTML
- 使用基于表格的布局 - 邮件客户端对 CSS 的支持不一致
- 内联 CSS 样式 - 外部样式表通常会被阻止
- 避免复杂的 CSS - 坚持使用基本的属性,如颜色、背景颜色、填充
- 使用网页安全字体 - Arial, Helvetica, Times New Roman 等
- 跨邮件客户端测试 - 使用 Litmus 或 Email on Acid 等工具
区块设计
- 保持简洁 - 复杂的布局可能无法一致地渲染
- 使用语义化 HTML - 有助于无障碍和渲染
- 提供备用方案 - 为不支持的产品特点提供优雅降级
- 考虑移动端 - 许多邮件在移动设备上阅读
代码质量
- 转义输出 - 正确使用
esc_html()、esc_url()、wp_kses_post() - 验证输入 - 检查属性并提供合理的默认值
- 优雅地处理错误 - 如果渲染失败,则返回原始内容
- 遵循 WordPress 编码标准 - 保持代码风格一致
故障排除
区块在邮件中不渲染
- 检查邮件支持 - 确保
supports.email设置为true - 验证回调 - 确认
render_email_callback已正确设置 - 钩子时机 - 确保筛选器在区块注册前添加
- 检查区块名称 - 确保区块名称完全匹配
邮件显示问题
- 在多个客户端中测试 - 不同的邮件客户端处理 HTML 的方式不同
- 验证 HTML - 使用 HTML 验证器检查错误
- 检查 CSS 支持 - 某些 CSS 属性在邮件中不受支持
- 使用表格进行布局 - 在邮件中比 CSS flexbox/网格更可靠
调试信息
启用调试日志记录以排查问题:
// 将此添加到 wp-config.php 以进行调试
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
// 邮件编辑将日志记录到 WordPress 调试日志
检查 WordPress 调试日志 (/wp-content/debug.log) 中与邮件编辑相关的消息。