458 lines
No EOL
15 KiB
Markdown
458 lines
No EOL
15 KiB
Markdown
# 电子邮件编辑器的区块注册
|
||
|
||
本指南解释了如何注册 WordPress 区块以支持在 WooCommerce 电子邮件编辑器中进行电子邮件渲染。电子邮件编辑器扩展了 WordPress 古腾堡区块,增加了电子邮件特定的渲染功能,允许区块生成与电子邮件客户端兼容的 HTML。
|
||
|
||
## 目录
|
||
|
||
- [概述](#overview)
|
||
- [区块配置](#block-configuration)
|
||
- [邮件支持属性](#email-support-property)
|
||
- [邮件渲染回调](#email-render-callback)
|
||
- [为邮件支持注册区块](#registering-blocks-for-email-support)
|
||
- [方法 1:使用 block_type_metadata_settings 过滤器](#method-1-using-block_type_metadata_settings-filter)
|
||
- [方法 2:直接区块注册](#method-2-direct-block-registration)
|
||
- [创建邮件区块渲染器](#creating-email-block-renderers)
|
||
- [抽象区块渲染器](#abstract-block-renderer)
|
||
- [渲染上下文](#rendering-context)
|
||
- [表格包装器助手](#table-wrapper-helper)
|
||
- [完整示例](#complete-example)
|
||
- [最佳实践](#best-practices)
|
||
- [故障排除](#troubleshooting)
|
||
|
||
## 概述
|
||
|
||
WooCommerce 邮件编辑器允许在邮件兼容的 HTML 中渲染 WordPress 区块。要使一个区块兼容邮件渲染,您需要:
|
||
|
||
1. **启用邮件支持**:在区块配置中设置 `supports.email = true`
|
||
2. **提供邮件渲染回调函数**:该函数生成邮件兼容的 HTML
|
||
3. **实现渲染逻辑**:将区块内容转换为邮件友好的标记
|
||
|
||
邮件编辑器会自动检测支持邮件的区块,并使用其自定义的渲染回调函数,而不是默认的 WordPress 区块渲染。
|
||
|
||
## 区块配置
|
||
|
||
### 电子邮件支持属性
|
||
|
||
要表明区块支持电子邮件渲染,请在区块的 `supports` 配置中将 `email` 属性设置为 `true`:
|
||
|
||
```php
|
||
$block_settings = array(
|
||
'name' => 'my-plugin/custom-block',
|
||
'title' => 'Custom Block',
|
||
'supports' => array(
|
||
'email' => true, // 启用电子邮件支持
|
||
// ... 其他支持
|
||
),
|
||
// ... 其他设置
|
||
);
|
||
```
|
||
|
||
### 邮件渲染回调
|
||
|
||
提供专门用于邮件渲染的自定义渲染回调:
|
||
|
||
```php
|
||
$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` 过滤器在注册期间修改块设置:
|
||
|
||
```php
|
||
/**
|
||
* 为自定义区块添加邮件支持。
|
||
*/
|
||
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 );
|
||
```
|
||
|
||
### 方法二:直接区块注册
|
||
|
||
您也可以直接注册支持邮件的区块:
|
||
|
||
```php
|
||
/**
|
||
* 注册一个支持邮件的自定义区块。
|
||
*/
|
||
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
|
||
<?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` 对象提供对主题选项和其他渲染上下文的访问:
|
||
|
||
```php
|
||
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` 提供了用于创建邮件兼容表格结构的实用工具:
|
||
|
||
```php
|
||
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
|
||
<?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
|
||
|
||
```javascript
|
||
/**
|
||
* 通讯区块的简单测试版本
|
||
*/
|
||
(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
|
||
|
||
1. **使用基于表格的布局** - 邮件客户端对 CSS 的支持不一致
|
||
2. **内联 CSS 样式** - 外部样式表通常会被阻止
|
||
3. **避免复杂的 CSS** - 坚持使用基本的属性,如颜色、背景颜色、填充
|
||
4. **使用网页安全字体** - Arial, Helvetica, Times New Roman 等
|
||
5. **跨邮件客户端测试** - 使用 Litmus 或 Email on Acid 等工具
|
||
|
||
### 区块设计
|
||
|
||
1. **保持简洁** - 复杂的布局可能无法一致地渲染
|
||
2. **使用语义化 HTML** - 有助于无障碍和渲染
|
||
3. **提供备用方案** - 为不支持的产品特点提供优雅降级
|
||
4. **考虑移动端** - 许多邮件在移动设备上阅读
|
||
|
||
### 代码质量
|
||
|
||
1. **转义输出** - 正确使用 `esc_html()`、`esc_url()`、`wp_kses_post()`
|
||
2. **验证输入** - 检查属性并提供合理的默认值
|
||
3. **优雅地处理错误** - 如果渲染失败,则返回原始内容
|
||
4. **遵循 WordPress 编码标准** - 保持代码风格一致
|
||
|
||
## 故障排除
|
||
|
||
### 区块在邮件中不渲染
|
||
|
||
1. **检查邮件支持** - 确保 `supports.email` 设置为 `true`
|
||
2. **验证回调** - 确认 `render_email_callback` 已正确设置
|
||
3. **钩子时机** - 确保筛选器在区块注册前添加
|
||
4. **检查区块名称** - 确保区块名称完全匹配
|
||
|
||
### 邮件显示问题
|
||
|
||
1. **在多个客户端中测试** - 不同的邮件客户端处理 HTML 的方式不同
|
||
2. **验证 HTML** - 使用 HTML 验证器检查错误
|
||
3. **检查 CSS 支持** - 某些 CSS 属性在邮件中不受支持
|
||
4. **使用表格进行布局** - 在邮件中比 CSS flexbox/网格更可靠
|
||
|
||
### 调试信息
|
||
|
||
启用调试日志记录以排查问题:
|
||
|
||
```php
|
||
// 将此添加到 wp-config.php 以进行调试
|
||
define( 'WP_DEBUG', true );
|
||
define( 'WP_DEBUG_LOG', true );
|
||
|
||
// 邮件编辑将日志记录到 WordPress 调试日志
|
||
```
|
||
|
||
检查 WordPress 调试日志 (`/wp-content/debug.log`) 中与邮件编辑相关的消息。 |