Gutenberg 区块样式:你真的懂它了吗?(源码剖析 gutenberg_block_css_is_active()
)
大家好,我是老码,今天咱们不聊诗和远方,就聊聊 WordPress Gutenberg 区块样式这档子事儿。很多小伙伴在使用 Gutenberg 编辑器的时候,经常会遇到一个问题:明明我给区块加了自定义样式,但页面上就是不生效,这是为啥呢?
今天,咱们就来扒一扒 WordPress 核心函数 gutenberg_block_css_is_active()
的源码,看看它到底是怎么判断区块样式是否应该加载的,顺便也给大家伙儿理理清 Gutenberg 区块样式加载的整个流程。
准备好了吗?系好安全带,老码要开车了!
一、背景知识:Gutenberg 区块样式加载机制
在深入 gutenberg_block_css_is_active()
之前,咱们先得搞清楚 Gutenberg 区块样式的几种加载方式:
-
内联样式(Inline Styles): 直接将 CSS 嵌入到 HTML 元素中。这种方式的优先级最高,但不利于维护和复用。
-
嵌入式样式(Embedded Styles): 将 CSS 嵌入到 HTML 文档的
<style>
标签中。这种方式的优先级高于外部样式,但仍然不利于维护和复用。 -
外部样式(External Styles): 将 CSS 样式写在单独的
.css
文件中,然后在 HTML 文档中通过<link>
标签引用。这种方式的优先级最低,但最利于维护和复用。
Gutenberg 区块样式主要采用后两种方式,尤其是外部样式。WordPress 会根据区块的使用情况,动态地加载相应的 CSS 文件。这也就是我们今天要研究的重点。
二、gutenberg_block_css_is_active()
函数源码剖析
好了,废话不多说,直接上代码!
/**
* Checks if the CSS for a block is active (loaded).
*
* @since 5.0.0
*
* @param string $name Block name including namespace.
*
* @return bool Whether the block CSS is active (loaded).
*/
function gutenberg_block_css_is_active( $name ) {
global $wp_registered_blocks;
if ( ! isset( $wp_registered_blocks[ $name ] ) ) {
return false;
}
$block = $wp_registered_blocks[ $name ];
if ( ! isset( $block->style ) && ! isset( $block->editor_style ) ) {
return true;
}
$handles = array_filter(
array(
isset( $block->style ) ? $block->style : null,
isset( $block->editor_style ) ? $block->editor_style : null,
)
);
foreach ( $handles as $handle ) {
if ( wp_style_is( $handle, 'queue' ) || wp_style_is( $handle, 'done' ) ) {
return true;
}
}
return false;
}
现在,咱们一行一行地解读这段代码:
-
function gutenberg_block_css_is_active( $name )
: 定义函数,接收一个参数$name
,表示区块的名称(包含命名空间)。 -
global $wp_registered_blocks;
: 声明全局变量$wp_registered_blocks
。这个变量存储了所有已注册的 Gutenberg 区块的信息。 -
if ( ! isset( $wp_registered_blocks[ $name ] ) ) { return false; }
: 判断$wp_registered_blocks
数组中是否存在以$name
为键的元素。如果不存在,说明该区块没有注册,直接返回false
,表示该区块的 CSS 没有加载。- 解释: 这一步非常重要,它确保了我们操作的是一个已经注册的区块。
-
$block = $wp_registered_blocks[ $name ];
: 将$wp_registered_blocks
数组中以$name
为键的元素赋值给变量$block
。$block
变量现在包含了该区块的所有信息,包括其样式信息。 -
if ( ! isset( $block->style ) && ! isset( $block->editor_style ) ) { return true; }
: 判断$block
对象中是否同时不存在style
和editor_style
属性。如果不存在,说明该区块没有定义任何样式,直接返回true
。- 解释: 这里有点反直觉,如果区块没有定义任何样式,函数反而返回
true
。这是因为 WordPress 认为,如果一个区块没有定义任何样式,那么它就不需要加载任何 CSS 文件,因此可以认为它的“CSS 是激活的”。
- 解释: 这里有点反直觉,如果区块没有定义任何样式,函数反而返回
-
$handles = array_filter( array( isset( $block->style ) ? $block->style : null, isset( $block->editor_style ) ? $block->editor_style : null, ) );
: 创建一个数组$handles
,其中包含了$block->style
和$block->editor_style
的值。然后使用array_filter()
函数过滤掉数组中的null
值。- 解释:
$block->style
表示区块在前端显示的 CSS 样式句柄(handle)。$block->editor_style
表示区块在编辑器中显示的 CSS 样式句柄。array_filter()
用于移除数组中的空值,避免后续处理出现问题。
- 解释:
-
foreach ( $handles as $handle ) { ... }
: 遍历$handles
数组,对每一个样式句柄进行判断。 -
if ( wp_style_is( $handle, 'queue' ) || wp_style_is( $handle, 'done' ) ) { return true; }
: 使用wp_style_is()
函数判断当前样式句柄$handle
是否已经加入到队列中('queue'
状态)或者已经加载完成('done'
状态)。如果满足其中一个条件,则返回true
,表示该区块的 CSS 已经加载。- 解释:
wp_style_is( $handle, 'queue' )
检查样式是否在 WordPress 的样式队列中,等待输出。wp_style_is( $handle, 'done' )
检查样式是否已经输出到页面上。- 如果样式处于这两种状态中的任何一种,就认为这个区块的CSS已经加载了。
- 解释:
-
return false;
: 如果遍历完$handles
数组后,仍然没有找到已经加载的样式句柄,则返回false
,表示该区块的 CSS 没有加载。
三、gutenberg_block_css_is_active()
函数的返回值
总结一下,gutenberg_block_css_is_active()
函数的返回值有三种情况:
返回值 | 含义 |
---|---|
true |
区块没有定义任何样式,或者区块的样式已经加入到队列中或者已经加载完成。 简单来说,它会返回true,当没有样式需要加载,或者样式已经成功加载。 |
false |
区块已经注册,并且定义了样式,但是该样式既没有加入到队列中,也没有加载完成。 简单来说,它会返回false,只有在定义了样式但是没有被加载的情况下 |
四、使用场景举例
-
条件加载区块 CSS: 你可以在主题或插件中使用
gutenberg_block_css_is_active()
函数,判断某个区块的 CSS 是否已经加载,然后根据结果决定是否需要手动加载该区块的 CSS。if ( ! gutenberg_block_css_is_active( 'my-plugin/my-block' ) ) { wp_enqueue_style( 'my-plugin-my-block', plugin_dir_url( __FILE__ ) . 'css/my-block.css' ); }
-
判断区块样式是否生效: 你可以在前端调试时使用
gutenberg_block_css_is_active()
函数,判断某个区块的样式是否已经生效。if ( wp.data.select( 'core/blocks' ).isBlockCSSActive( 'my-plugin/my-block' ) ) { console.log( 'my-plugin/my-block CSS is active' ); } else { console.log( 'my-plugin/my-block CSS is NOT active' ); }
五、常见问题及解决方案
-
区块样式不生效: 如果你的区块样式不生效,首先要检查你的区块是否已经正确注册。然后,检查你的 CSS 文件是否已经正确加载。你可以使用浏览器的开发者工具来检查 CSS 文件是否加载成功,以及 CSS 规则是否被正确应用。
-
重复加载区块 CSS: 如果你发现某个区块的 CSS 被重复加载,可能是因为你在多个地方都手动加载了该区块的 CSS。你可以使用
gutenberg_block_css_is_active()
函数来避免重复加载。 -
编辑器样式和前端样式不一致: 如果你发现区块在编辑器中的样式和在前端显示的样式不一致,可能是因为你使用了不同的 CSS 文件来定义编辑器样式和前端样式。你可以使用
$block->editor_style
和$block->style
属性来分别指定编辑器样式和前端样式的句柄。
六、总结与展望
gutenberg_block_css_is_active()
函数是 WordPress Gutenberg 编辑器中一个非常重要的函数,它可以帮助我们判断区块样式是否已经加载。通过深入理解该函数的源码,我们可以更好地控制 Gutenberg 区块样式的加载,避免出现样式不生效或重复加载等问题。
希望今天的分享对大家有所帮助。记住,理解源码是解决问题的关键。下次遇到 Gutenberg 区块样式的问题,不妨回头看看这段代码,也许你会发现新的灵感!
好了,今天的讲座就到这里。下次有机会,老码再和大家聊聊 Gutenberg 区块开发的更多技巧。
祝大家编程愉快!