woocommerce/packages/php/email-editor/docs/zh-cn/rendering.md
2026-04-15 10:18:01 +08:00

658 lines
No EOL
20 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 邮件渲染
**邮件渲染器类**旨在将包含基于区块内容(保存在古腾堡编辑器中)的 WordPress 文章渲染为适合邮件传递的 HTML 和纯文本。这些类提供了将区块编辑器内容转换为邮件兼容格式的核心功能。
邮件渲染系统包含**核心区块集成**,为 WordPress 核心区块提供专用的渲染器。此集成对于生成邮件客户端兼容的 HTML 输出至关重要——如果没有这些特定于区块的渲染器,渲染出的 HTML 将不适合邮件客户端。
## 目录
- [通过 DI 容器检索服务](#retrieving-services-via-di-container)
- [引导程序](#bootstrapping)
- [渲染器类](#renderer-classes)
- [Renderer](#renderer)
- [Content_Renderer](#content_renderer)
- [核心区块集成](#core-blocks-integration)
- [表格容器帮助](#table-wrapper-helper)
- [样式帮助](#styles-helper)
- [集成示例](#integration-example)
## 通过 DI 容器获取服务
访问渲染服务的最简单方式是通过 DI 容器。`Automattic\WooCommerce\EmailEditor\Email_Editor_Container` 类提供了一个依赖注入容器,可用于轻松获取渲染器服务。
以下是获取渲染器服务的方法:
```php
use Automattic\WooCommerce\EmailEditor\Email_Editor_Container;
use Automattic\WooCommerce\EmailEditor\Engine\Renderer\Renderer;
use Automattic\WooCommerce\EmailEditor\Engine\Renderer\ContentRenderer\Content_Renderer;
// 获取容器实例
$container = Email_Editor_Container::container();
// 获取渲染器服务
$renderer = $container->get( Renderer::class );
$content_renderer = $container->get( Content_Renderer::class );
```
## 引导启动
渲染引擎需要使用 `Automattic\WooCommerce\EmailEditor\Bootstrap` 类及其 `init` 方法进行引导启动。
此引导过程会注册必要的操作回调。它必须在 WordPress 的 `init` 操作被触发之前调用,最晚在 `plugins_loaded` 操作时调用。之所以需要如此早的初始化,是因为引导过程会挂钩到核心区块的注册,而该注册发生在 `init` 钩子之前。
**示例:**
```php
use Automattic\WooCommerce\EmailEditor\Email_Editor_Container;
use Automattic\WooCommerce\EmailEditor\Bootstrap;
// 获取容器实例
$container = Email_Editor_Container::container();
// 获取 Bootstrap 服务并进行初始化
$bootstrap = $container->get( Bootstrap::class );
$bootstrap->init();
```
## 渲染器类
### Renderer
`Automattic\WooCommerce\EmailEditor\Engine\Renderer\Renderer` 类负责渲染完整的 HTML 文档,包括 head 部分的元信息和 body 标签内的内容。该类提供了一个完整的电子邮件模板结构。
**主要方法:**
```php
/**
* 渲染电子邮件模板
*
* @param \WP_Post $post 文章对象。
* @param string $subject 电子邮件主题。
* @param string $pre_header 电子邮件预标题或预览文本,是收件箱中主题行后面的简短文本片段。参见 https://kb.mailpoet.com/article/418-preview-text
* @param string $language 电子邮件语言。
* @param string $meta_robots 可选字符串。发送时可以留空,但当您想在浏览器中显示电子邮件 html 时,可以提供一个值(例如 noindex, nofollow
* @param string $template_slug 可选区块模板别名,用于电子邮件没有关联模板的情况。
* @return array
*/
public function render(
\WP_Post $post,
string $subject,
string $pre_header,
string $language = 'en',
string $meta_robots = '',
string $template_slug = ''
): array
```
**返回:** 一个包含以下内容的数组:
- `html`: 完整的 HTML 电子邮件内容
- `text`: 电子邮件的纯文本版本
**使用示例:**
```php
$post = get_post( $post_id );
// 文章有关联的区块模板,否则将使用回退的空白模板,该模板仅渲染文章内容
$rendered_email = $renderer->render(
$post,
'订单确认',
'您的订单已确认',
'en'
);
// 通过传递模板别名字符串显式指定模板
$rendered_email = $renderer->render(
$post,
'订单确认',
'您的订单已确认',
'en',
'',
'my-email-template-slug'
);
$html_content = $rendered_email['html'];
$text_content = $rendered_email['text'];
```
### Content_Renderer
`Automattic\WooCommerce\EmailEditor\Engine\Renderer\ContentRenderer\Content_Renderer` 类负责仅渲染区块模板内容和文章的 HTML。区块模板必须包含一个 `core/post-content` 区块。
**方法:**
#### `render()`
返回渲染后的 HTML 内容作为带有内联 CSS 样式的字符串。
```php
/**
* 使用内联 CSS 样式渲染内容。
*
* @param WP_Post $post 文章对象。
* @param WP_Block_Template $template 区块模板。
* @return string 带有内联样式的渲染后 HTML 内容。
*/
public function render(
WP_Post $post,
WP_Block_Template $template
): string
```
**用法示例:**
```php
$post = get_post( $post_id );
$template_id = get_stylesheet() . '//' . $template_slug;
$template = get_block_template( $template_id );
$content = $content_renderer->render( $post, $template );
```
#### `render_without_css_inline()`
返回渲染后的 HTML 和收集的 CSS 样式作为数组,但不内联 CSS。这由 `Renderer` 类使用,该类将这些内容样式与模板样式合并为一次内联处理。
```php
/**
* 渲染内容并收集 CSS 样式而不内联它们。
*
* @param WP_Post $post 文章对象。
* @param WP_Block_Template $template 区块模板。
* @return array{html: string, styles: string} 渲染的 HTML 和收集的 CSS。
*/
public function render_without_css_inline(
WP_Post $post,
WP_Block_Template $template
): array
```
**返回:** 一个包含以下内容的数组:
- `html`:渲染的 HTML 内容(无内联样式)
- `styles`:收集的 CSS 字符串(无 `<style>` 包装)
**示例用法:**
```php
$post = get_post( $post_id );
$template_id = get_stylesheet() . '//' . $template_slug;
$template = get_block_template( $template_id );
$result = $content_renderer->render_without_css_inline( $post, $template );
$html = $result['html'];
$styles = $result['styles'];
```
## 核心区块集成
该软件包为最常用的 WordPress 核心区块提供了专门的渲染器,并计划最终覆盖所有核心区块。这些独立的区块渲染器位于 [packages/php/email-editor/src/Integrations/Core/Renderer/Blocks](https://github.com/woocommerce/woocommerce/tree/trunk/packages/php/email-editor/src/Integrations/Core/Renderer/Blocks) 目录中。
**用法:**
核心区块的区块渲染器在核心区块注册时与其关联,这发生得非常早(例如,从 `plugins_loaded` 回调中),因此核心区块集成需要尽早初始化。
如果您使用 `Automattic\WooCommerce\EmailEditor\Bootstrap` 类,核心集成会自动为您设置。如果您想手动设置,请参考 `Automattic\WooCommerce\EmailEditor\Bootstrap` 的 init 方法。
## 表格容器助手
`Automattic\WooCommerce\EmailEditor\Integrations\Utils\Table_Wrapper_Helper` 类提供了用于生成邮件兼容表格结构的实用方法。由于邮件客户对 CSS 的支持级别各不相同,因此通常需要使用基于表格的布局,以确保在不同邮件客户中实现一致的渲染效果。
### 默认表格属性
该助手使用以下默认表格属性以实现最佳的电子邮件客户端兼容性:
```php
array(
'border' => '0',
'cellpadding' => '0',
'cellspacing' => '0',
'role' => 'presentation',
)
```
### 可用方法
#### `render_table_wrapper()`
渲染一个完整的表格结构,可选的表格、单元格和行属性。
```php
/**
* 为邮件区块渲染一个表格包装器。
*
* @param string $content 要包装的内容(例如,'{block_content}')。
* @param array $table_attrs 要与默认值合并的表格属性。
* @param array $cell_attrs 单元格属性。
* @param array $row_attrs 行属性。
* @param bool $render_cell 是否渲染 td 包装器(默认为 true
* @return string 生成的表格包装器 HTML。
*/
public static function render_table_wrapper(
string $content,
array $table_attrs = array(),
array $cell_attrs = array(),
array $row_attrs = array(),
bool $render_cell = true
): string
```
**示例用法:**
```php
$table_html = Table_Wrapper_Helper::render_table_wrapper(
'<p>Email content here</p>',
array(
'width' => '100%',
'style' => 'max-width: 600px;'
),
array(
'align' => 'center',
'style' => 'padding: 20px;'
),
array(
'style' => 'background-color: #f0f0f0;'
)
);
```
**输出:**
```html
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
width="100%"
style="max-width: 600px;"
>
<tbody>
<tr style="background-color: #f0f0f0;">
<td align="center" style="padding: 20px;">
<p>Email content here</p>
</td>
</tr>
</tbody>
</table>
```
#### `render_outlook_table_wrapper()`
渲染一个完整的表格结构,包裹在 Outlook 特定的条件注释中。
```php
/**
* 使用条件注释渲染 Outlook 特定的表格包装器。
*
* @param string $content 要包裹的内容(例如 '{block_content}')。
* @param array $table_attrs 要与默认值合并的表格属性。
* @param array $cell_attrs 单元格属性。
* @param array $row_attrs 行属性。
* @param bool $render_cell 是否渲染 td 包装器(默认为 true
* @return string 生成的表格包装器 HTML。
*/
public static function render_outlook_table_wrapper(
string $content,
array $table_attrs = array(),
array $cell_attrs = array(),
array $row_attrs = array(),
bool $render_cell = true
): string
```
**用法示例:**
```php
$outlook_table = Table_Wrapper_Helper::render_outlook_table_wrapper(
'<p>Outlook-specific table content</p>',
array('width' => '100%'),
array('align' => 'center')
);
```
**输出:**
```html
<!--[if mso | IE]><table border="0" cellpadding="0" cellspacing="0" role="presentation" width="100%"><tbody><tr><td align="center"><![endif]-->
<p>Outlook-specific table content</p>
<!--[if mso | IE]></td></tr></tbody></table><![endif]-->
```
#### `render_table_cell()`
渲染单个表格单元格 (`<td>`) 元素,支持可选属性。
```php
/**
* 渲染一个表格单元格。
*
* @param string $content 要包裹的内容。
* @param array $cell_attrs 单元格属性。
* @return string 生成的表格单元格 HTML。
*/
public static function render_table_cell(
string $content,
array $cell_attrs = array()
): string
```
**示例用法:**
```php
use Automattic\WooCommerce\EmailEditor\Integrations\Utils\Table_Wrapper_Helper;
$cell_html = Table_Wrapper_Helper::render_table_cell(
'<p>Hello World</p>',
array(
'align' => 'center',
'style' => 'padding: 20px;'
)
);
```
**输出:**
```html
<td align="center" style="padding: 20px;"><p>Hello World</p></td>
```
#### `render_outlook_table_cell()`
渲染一个包裹在 Outlook 特定条件评论中的表格单元格,以提高与 Microsoft Outlook 的兼容性。
```php
/**
* 使用条件评论渲染一个 Outlook 特定的表格单元格。
*
* @param string $content 要包裹的内容。
* @param array $cell_attrs 单元格属性。
* @return string 生成的带有 Outlook 条件评论的表格单元格 HTML。
*/
public static function render_outlook_table_cell(
string $content,
array $cell_attrs = array()
): string
```
**用法示例:**
```php
$outlook_cell = Table_Wrapper_Helper::render_outlook_table_cell(
'<p>Outlook-specific content</p>',
array('align' => 'center')
);
```
**输出:**
```html
<!--[if mso | IE]><td align="center"><![endif]-->
<p>Outlook-specific content</p>
<!--[if mso | IE]></td><![endif]-->
```
## 样式帮助器
`Styles_Helper` 类提供实用方法,用于处理从 WordPress 区块属性派生的电子邮件兼容内联样式。
### 可用方法
#### `parse_value()`
从带有单位的 CSS 字符串中解析数值。
```php
/**
* 从字符串中解析数值。
*
* @param string $value 包含值和单位的字符串值。
* @return float
*/
public static function parse_value( string $value ): float
```
**示例用法:**
```php
use Automattic\WooCommerce\EmailEditor\Integrations\Utils\Styles_Helper;
$width = Styles_Helper::parse_value( '12.5px' ); // 返回 12.5
$height = Styles_Helper::parse_value( '100%' ); // 返回 100.0
$invalid = Styles_Helper::parse_value( 'invalid' ); // 返回 0.0
```
#### `parse_styles_to_array()`
将 CSS 样式字符串转换为关联数组。
```php
/**
* 将样式字符串解析为数组。
*
* @param string $styles 样式字符串。
* @return array
*/
public static function parse_styles_to_array( string $styles ): array
```
**用法示例:**
```php
$styles = 'margin: 10px; padding: 5px; color: red;';
$parsed = Styles_Helper::parse_styles_to_array( $styles );
/*
示例返回值:
array(
'margin' => '10px',
'padding' => '5px',
'color' => 'red',
)
*/
```
#### `get_normalized_block_styles()`
通过将颜色别名转换为实际颜色值来规范化区块属性。
```php
/**
* 通过将颜色别名转换为实际颜色值来获取规范化的区块样式。
*
* 此方法通过使用渲染上下文将颜色相关的属性(如 backgroundColor、textColor、borderColor 和 linkColor从别名转换为实际颜色值来处理它们的规范化。
*
* @param array $block_attributes 包含颜色别名的区块属性。
* @param Rendering_Context $rendering_context 用于颜色翻译的渲染上下文。
* @return array 包含已翻译颜色值的规范化区块样式。
*/
public static function get_normalized_block_styles( array $block_attributes, Rendering_Context $rendering_context ): array
```
**使用示例:**
```php
$block_attributes = array(
'backgroundColor' => 'primary',
'textColor' => 'secondary',
'style' => array( 'spacing' => array( 'padding' => '10px' ) )
);
$normalized = Styles_Helper::get_normalized_block_styles( $block_attributes, $rendering_context );
/*
示例返回值:
array(
'spacing' => array(
'padding' => '10px',
),
'color' => array(
'background' => '#ff0000', // 假设 'primary' 翻译为 '#ff0000'
'text' => '#00ff00', // 假设 'secondary' 翻译为 '#00ff00'
),
)
*/
```
#### `get_styles_from_block()`
WordPress 样式引擎的包装器,确保返回结构。
```php
/**
* wp_style_engine_get_styles 的包装器,确保返回所有值。
*
* @param array $block_styles 区块样式数组。
* @param bool $skip_convert_vars 如果为 true--wp_preset--spacing--x 类型的值将保留为原始的 var:preset:spacing:x 格式。
* @return array {
* @type string $css 一个 CSS 规则集或声明区块,
* 格式化为可放置在 HTML `style` 属性或标签中。
* @type string[] $declarations 一个 CSS 定义的关联数组,
* 例如 `array( "$property" => "$value", "$property" => "$value" )`。
* @type string $classnames 由空格分隔的类名。
* }
*/
public static function get_styles_from_block( array $block_styles, $skip_convert_vars = false )
```
**用法示例:**
```php
$result = Styles_Helper::get_styles_from_block( $block_styles );
/*
示例返回值:
array(
'css' => 'padding: 10px; color: red;',
'declarations' => array(
'padding' => '10px',
'color' => 'red',
),
'classnames' => 'has-padding has-color-red',
)
*/
```
#### `extend_block_styles()`
使用额外的 CSS 声明扩展现有区块样式。
```php
/**
* 使用 CSS 声明扩展区块样式。
*
* @param array $block_styles WP_Style_Engine 样式数组(必须包含 'declarations' 和 'css' 键)。
* @param array $css_declarations CSS 定义的关联数组,
* 例如 `array( "$property" => "$value", "$property" => "$value" )`。
* @return array {
* @type string $css 一个 CSS 规则集或声明块,
* 格式化为可放置在 HTML `style` 属性或标签中。
* @type string[] $declarations CSS 定义的关联数组,
* 例如 `array( "$property" => "$value", "$property" => "$value" )`。
* @type string $classnames 由空格分隔的类名。
* }
*/
public static function extend_block_styles( array $block_styles, $css_declarations )
```
**用法示例:**
```php
$extended = Styles_Helper::extend_block_styles( $block_styles, array(
'margin' => '20px',
'color' => 'red'
) );
/*
示例返回值:
array(
'declarations' => array(
'padding' => '10px',
'margin' => '20px',
'color' => 'red',
),
'css' => 'padding: 10px; margin: 20px; color: red;',
'classnames' => 'test-class',
)
*/
```
#### `get_block_styles()`
获取经过处理并带有过滤和返回值类型控制的区块样式的综合方法。
```php
/**
* 获取区块样式。
*
* @param array $block_attributes 区块属性。
* @param Rendering_Context $rendering_context 渲染上下文。
* @param array $properties 要包含的样式属性列表。支持的值:
* 'spacing', 'padding', 'margin',
* 'border', 'border-width', 'border-style', 'border-radius', 'border-color',
* 'background', 'background-color', 'color',
* 'typography', 'font-size', 'font-family', 'font-weight', 'text-align'.
* @return array {
* @type string $css 一个 CSS 规则集或声明块,
* 格式化为可放置在 HTML `style` 属性或标签中。
* @type string[] $declarations 一个 CSS 定义的关联数组,
* 例如 `array( "$property" => "$value", "$property" => "$value" )`。
* @type string $classnames 由空格分隔的类名。
* }
*/
public static function get_block_styles( array $block_attributes, Rendering_Context $rendering_context, array $properties )
```
**支持的属性:**
- `spacing`, `padding`, `margin`
- `border`, `border-width`, `border-style`, `border-radius`, `border-color`
- `background`, `background-color`, `color`
- `typography`, `font-size`, `font-family`, `font-weight`, `text-align`
**使用示例:**
```php
$styles = Styles_Helper::get_block_styles( $block_attributes, $rendering_context, array( 'spacing', 'color' ) );
/*
示例返回值:
array(
'declarations' => array(
'padding' => '10px',
'color' => '#ff0000',
),
'css' => 'padding: 10px; color: #ff0000;',
'classnames' => 'has-text-color',
)
*/
```
## 集成示例
以下是这些类在典型邮件渲染工作流中的协同工作方式:
```php
use Automattic\WooCommerce\EmailEditor\Email_Editor_Container;
use Automattic\WooCommerce\EmailEditor\Bootstrap;
use Automattic\WooCommerce\EmailEditor\Engine\Renderer\Renderer;
// 从容器获取服务
$container = Email_Editor_Container::container();
// 初始化渲染引擎(必须在 WordPress init 操作前调用)
$bootstrap = $container->get( Bootstrap::class );
$bootstrap->init();
// 从文章渲染邮件
// 获取渲染器服务
$renderer = $container->get( Renderer::class );
// 渲染完整的邮件
$post = get_post( $email_post_id );
$email_data = $renderer->render(
$post,
'欢迎使用我们的商店!',
'谢谢您的购买',
'en'
);
```
这允许灵活的邮件渲染,您可以根据具体需求获取完整的邮件文档或仅获取内容区块。