区块支持 是允许区块声明支持某些功能的 API。
当区块声明支持特定样式组或属性(例如 “spacing” 或 “spacing.padding”)时,该区块的属性会被扩展,以包含一个 style 对象。
例如:
{
"attributes": {
"style": {
"spacing": {
"margin": {
"top": "10px"
},
"padding": "1em"
},
"typography": {
"fontSize": "2.2rem"
}
}
}
}
使用该对象,Style Engine 可以生成用于设置区块元素样式的类名和 CSS。
全局函数 wp_style_engine_get_styles 接受一个样式对象作为第一个参数,并会输出编译后的 CSS 以及一个 CSS 声明属性/值对的数组。
$block_styles = array(
'spacing' => array( 'padding' => '10px', 'margin' => array( 'top' => '1em') ),
'typography' => array( 'fontSize' => '2.2rem' ),
);
$styles = wp_style_engine_get_styles(
$block_styles
);
print_r( $styles );
/*
array(
'css' => 'padding:10px;margin-top:1em;font-size:2.2rem',
'declarations' => array( 'padding' => '10px', 'margin-top' => '1em', 'font-size' => '2.2rem' )
)
*/
使用场景
在 注册区块支持 时,可以在区块支持配置数组中传入一个 “apply” 回调,用于添加或扩展区块支持属性,使其包含 “class” 或 “style” 属性。
如果区块已选择启用该区块支持,则在前端 HTML 中渲染时,“class” 和 “style” 的值会相应地应用于该区块元素的 “class” 和 “style” 属性。请注意,这仅适用于服务端渲染的区块,例如 Site Title 区块。
该回调接收 $block_type 和 $block_attributes 作为参数。$block_attributes 中的 style 属性仅包含原始样式对象(如果已为区块设置样式),而不包含将应用于区块 HTML 元素的任何 CSS 或类名。
这正是 wp_style_engine_get_styles 的实用之处:它会生成 CSS,并在适当时生成类名,以添加到最终渲染区块标记中的 “style” 和 “class” HTML 属性中。
下面是 颜色区块支持 工作原理的一个非常简化的版本:
function gutenberg_apply_colors_support( $block_type, $block_attributes ) {
// 从 style 对象中获取颜色样式。
$block_color_styles = isset( $block_attributes['style']['color'] ) ? $block_attributes['style']['color'] : null;
// 由于我们只需要颜色样式,因此仅将颜色样式传递给 Style Engine。
$styles = wp_style_engine_get_styles( array( 'color' => $block_color_styles ) );
// 返回将应用于区块 HTML 元素的生成样式。
return array(
'style' => $styles['css'],
'class' => $styles['classnames']
);
}
// 注册区块支持。
WP_Block_Supports::get_instance()->register(
'colors',
array(
'register_attribute' => 'gutenberg_register_colors_support',
'apply' => 'gutenberg_apply_colors_support',
)
);
Style Engine 为以下核心区块支持生成样式:
- background(背景)
- border(边框)
- color(颜色)
- dimensions(尺寸)
- shadow(阴影)
- spacing(间距)
- typography(排版)
检查区块支持和跳过序列化
在将区块样式对象传递给 Style Engine 之前,需要考虑:
- 主题是否选择支持特定的区块样式,以及
- 区块是否选择“跳过序列化”该特定区块样式,也就是选择不自动将样式应用于区块元素(通常是为了通过区块内部来实现)。更多信息请参阅 区块 API 文档。
如果区块:
- 不支持某种样式,或
- 跳过该样式的序列化
你可能希望在将样式对象传递给 Style Engine 之前,借助以下两个函数从样式对象中移除这些样式值:
- wp_should_skip_block_supports_serialization()
- block_has_support()
现在,我们可以更新上面的 “apply” 回调代码,使其仅在区块支持该样式且不跳过序列化时返回 “style” 和 “class”:
function gutenberg_apply_colors_support( $block_type, $block_attributes ) {
// 返回值。
$attributes = array();
// 如果区块跳过所有区块支持的序列化,则提前返回。
if ( wp_should_skip_block_supports_serialization( $block_type, 'color' ) ) {
return $attributes;
}
// 检查是否支持以及是否跳过序列化。
$has_text_support = block_has_support( $block_type, array( 'color', 'text' ), false );
$has_background_support = block_has_support( $block_type, array( 'color', 'background' ), false );
$skips_serialization_of_color_text = wp_should_skip_block_supports_serialization( $block_type, 'color', 'text' );
$skips_serialization_of_color_background = wp_should_skip_block_supports_serialization( $block_type, 'color', 'background' );
// 从 style 对象中获取颜色样式。
$block_color_styles = isset( $block_attributes['style']['color'] ) ? $block_attributes['style']['color'] : null;
// 即将传递给 wp_style_engine_get_styles() 的修改后样式对象。
$color_block_styles = array();
// 根据区块是否支持且不跳过序列化来设置颜色样式值。
$color_block_styles['text'] = null;
$color_block_styles['background'] = null;
if ( $has_text_support && ! $skips_serialization_of_color_text ) {
$color_block_styles['text'] = $block_color_styles['text'] ?? null;
}
if ( $has_background_support && ! $skips_serialization_of_color_background ) {
$color_block_styles['background'] = $block_color_styles['background'] ?? null;
}
// 将颜色样式传递给 Style Engine,但不包括不受支持或跳过序列化的样式。
$styles = wp_style_engine_get_styles( array( 'color' => $color_block_styles ) );
// 返回将应用于区块 HTML 元素的生成样式。
return array(
'style' => $styles['css'],
'class' => $styles['classnames']
);
}
从预设生成类名和 CSS 自定义选择器
theme.json 的许多预设会在前端同时生成 CSS 自定义属性和 CSS 规则(由选择器和 CSS 声明组成)。
使用这些预设为区块设置样式,通常涉及将选择器添加到区块的 “className” 属性中。
对于可以具有预设值的样式(例如文本颜色和字体族),Style Engine 知道如何使用预设 slug 来构造类名。
为了区分 CSS 值和预设值,Style Engine 期望一种特殊格式。
预设值必须遵循 var:preset|<PRESET_TYPE>|<PRESET_SLUG> 模式。
当 Style Engine 遇到这些值时,它会解析这些值,并在需要时创建 var(--wp--preset--font-size--small) 这样的 CSS 值和/或生成类名。
示例:
// 假设区块属性样式包含值为 "small" 的 fontSize 预设 slug。
// $block_attributes['fontSize'] = 'var:preset|font-size|small';
$preset_font_size = "var:preset|font-size|{$block_attributes['fontSize']}";
// 现在假设区块属性样式包含值为 "blue" 的 backgroundColor 预设 slug。
// $block_attributes['backgroundColor'] = 'var:preset|color|blue';
$preset_background_color = "var:preset|color|{$block_attributes['backgroundColor']}";
$block_styles = array(
'typography' => array( 'fontSize' => $preset_font_size ),
'color' => array( 'background' => $preset_background_color ),
'spacing' => array( 'padding' => '10px', 'margin' => array( 'top' => '1em') ),
);
$styles = wp_style_engine_get_styles(
$block_styles
);
print_r( $styles );
/*
array(
'css' => 'background-color:var(--wp--preset--color--blue);padding:10px;margin-top:1em;font-size:var(--wp--preset--font-size--small);',
'declarations' => array(
'background-color' => 'var(--wp--preset--color--blue)',
'padding' => '10px',
'margin-top' => '1em',
'font-size' => 'var(--wp--preset--font-size--small)',
),
'classnames' => 'has-background has-blue-background-color has-small-font-size',
)
*/
如果您不希望 Style Engine 在生成的 CSS 字符串中也输出 CSS 自定义变量(例如,在同时向区块元素应用 CSS 规则和类名时,可能并不希望输出这些变量),您可以在选项数组中传入 'convert_vars_to_classnames' => true。
该标志表示“将变量转换为类名,并且不要将变量输出到 CSS 中”。因此,Style Engine 将仅生成所需的类名,并在 CSS 中省略 CSS 自定义变量。
使用上面的示例代码,观察传入该选项时的不同输出:
$options = array(
'convert_vars_to_classnames' => true,
);
$styles = wp_style_engine_get_styles(
$block_styles,
$options
);
print_r( $styles );
/*
array(
'css' => 'padding:10px;margin-top:1em;',
'declarations' => array(
'padding' => '10px',
'margin-top' => '1em',
),
'classnames' => 'has-background has-blue-background-color has-small-font-size',
)
*/
阅读更多关于全局样式、预设 CSS 自定义属性和主题支持的信息。