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

20 KiB
Raw Permalink Blame History

邮件渲染

邮件渲染器类旨在将包含基于区块内容(保存在古腾堡编辑器中)的 WordPress 文章渲染为适合邮件传递的 HTML 和纯文本。这些类提供了将区块编辑器内容转换为邮件兼容格式的核心功能。

邮件渲染系统包含核心区块集成,为 WordPress 核心区块提供专用的渲染器。此集成对于生成邮件客户端兼容的 HTML 输出至关重要——如果没有这些特定于区块的渲染器,渲染出的 HTML 将不适合邮件客户端。

目录

通过 DI 容器获取服务

访问渲染服务的最简单方式是通过 DI 容器。Automattic\WooCommerce\EmailEditor\Email_Editor_Container 类提供了一个依赖注入容器,可用于轻松获取渲染器服务。

以下是获取渲染器服务的方法:

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 钩子之前。

示例:

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 标签内的内容。该类提供了一个完整的电子邮件模板结构。

主要方法:

/**
 * 渲染电子邮件模板
 *
 * @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: 电子邮件的纯文本版本

使用示例:

$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 样式的字符串。

/**
 * 使用内联 CSS 样式渲染内容。
 *
 * @param WP_Post           $post 文章对象。
 * @param WP_Block_Template $template 区块模板。
 * @return string 带有内联样式的渲染后 HTML 内容。
 */
public function render(
    WP_Post $post,
    WP_Block_Template $template
): string

用法示例:

$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 类使用,该类将这些内容样式与模板样式合并为一次内联处理。

/**
 * 渲染内容并收集 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> 包装)

示例用法:

$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 目录中。

用法: 核心区块的区块渲染器在核心区块注册时与其关联,这发生得非常早(例如,从 plugins_loaded 回调中),因此核心区块集成需要尽早初始化。

如果您使用 Automattic\WooCommerce\EmailEditor\Bootstrap 类,核心集成会自动为您设置。如果您想手动设置,请参考 Automattic\WooCommerce\EmailEditor\Bootstrap 的 init 方法。

表格容器助手

Automattic\WooCommerce\EmailEditor\Integrations\Utils\Table_Wrapper_Helper 类提供了用于生成邮件兼容表格结构的实用方法。由于邮件客户对 CSS 的支持级别各不相同,因此通常需要使用基于表格的布局,以确保在不同邮件客户中实现一致的渲染效果。

默认表格属性

该助手使用以下默认表格属性以实现最佳的电子邮件客户端兼容性:

array(
    'border'      => '0',
    'cellpadding' => '0',
    'cellspacing' => '0',
    'role'        => 'presentation',
)

可用方法

render_table_wrapper()

渲染一个完整的表格结构,可选的表格、单元格和行属性。

/**
 * 为邮件区块渲染一个表格包装器。
 *
 * @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

示例用法:

$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;'
    )
);

输出:

<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 特定的条件注释中。

/**
 * 使用条件注释渲染 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

用法示例:

$outlook_table = Table_Wrapper_Helper::render_outlook_table_wrapper(
    '<p>Outlook-specific table content</p>',
    array('width' => '100%'),
    array('align' => 'center')
);

输出:

<!--[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>) 元素,支持可选属性。

/**
 * 渲染一个表格单元格。
 *
 * @param string $content 要包裹的内容。
 * @param array  $cell_attrs 单元格属性。
 * @return string 生成的表格单元格 HTML。
 */
public static function render_table_cell(
    string $content,
    array $cell_attrs = array()
): string

示例用法:

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;'
    )
);

输出:

<td align="center" style="padding: 20px;"><p>Hello World</p></td>

render_outlook_table_cell()

渲染一个包裹在 Outlook 特定条件评论中的表格单元格,以提高与 Microsoft Outlook 的兼容性。

/**
 * 使用条件评论渲染一个 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

用法示例:

$outlook_cell = Table_Wrapper_Helper::render_outlook_table_cell(
    '<p>Outlook-specific content</p>',
    array('align' => 'center')
);

输出:

<!--[if mso | IE]><td align="center"><![endif]-->
<p>Outlook-specific content</p>
<!--[if mso | IE]></td><![endif]-->

样式帮助器

Styles_Helper 类提供实用方法,用于处理从 WordPress 区块属性派生的电子邮件兼容内联样式。

可用方法

parse_value()

从带有单位的 CSS 字符串中解析数值。

/**
 * 从字符串中解析数值。
 *
 * @param string $value 包含值和单位的字符串值。
 * @return float
 */
public static function parse_value( string $value ): float

示例用法:

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 样式字符串转换为关联数组。

/**
 * 将样式字符串解析为数组。
 *
 * @param string $styles 样式字符串。
 * @return array
 */
public static function parse_styles_to_array( string $styles ): array

用法示例:

$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()

通过将颜色别名转换为实际颜色值来规范化区块属性。

/**
 * 通过将颜色别名转换为实际颜色值来获取规范化的区块样式。
 *
 * 此方法通过使用渲染上下文将颜色相关的属性(如 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

使用示例:

$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 样式引擎的包装器,确保返回结构。

/**
 * 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 )

用法示例:

$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 声明扩展现有区块样式。

/**
 * 使用 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 )

用法示例:

$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()

获取经过处理并带有过滤和返回值类型控制的区块样式的综合方法。

/**
 * 获取区块样式。
 *
 * @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

使用示例:

$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',
)
*/

集成示例

以下是这些类在典型邮件渲染工作流中的协同工作方式:

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'
);

这允许灵活的邮件渲染,您可以根据具体需求获取完整的邮件文档或仅获取内容区块。