各位代码爱好者,今天咱来聊聊WordPress里一个有点意思的函数:get_post_block_type()
。 别看名字平平无奇,它可是WordPress区分文章里那些花里胡哨的“区块”的大侦探。 咱们的目标是,拆解这个函数,看看它是怎么从一堆文本里揪出各种区块类型的。
一、先来认识一下咱们的侦探:get_post_block_type()
这个函数的作用很简单,就是从文章内容中提取出第一个出现的区块的类型。 比如,文章开头第一个区块是个段落,它就返回 core/paragraph
。 如果文章里压根就没区块,或者内容为空,它就乖乖地返回 null
。
先看下源码的庐山真面目:
/**
* Retrieves the block type of the first block in the content of a post.
*
* @since 5.0.0
*
* @param WP_Post|int|null $post Optional. Post ID or WP_Post object. Default is global $post.
* @return string|null Block type string if found. Null if not found.
*/
function get_post_block_type( $post = null ) {
$post = get_post( $post );
if ( ! $post ) {
return null;
}
$blocks = parse_blocks( $post->post_content );
if ( ! $blocks ) {
return null;
}
if ( ! isset( $blocks[0]['blockName'] ) ) {
return null;
}
return $blocks[0]['blockName'];
}
二、拆解侦探的办案流程
-
确认身份:
get_post( $post )
首先,函数要确认它要侦查的是哪个文章。
get_post()
函数负责把传入的参数(文章ID或者文章对象)转化为一个标准的WP_Post
对象。 如果传入的是空值,它就尝试使用全局的$post
对象。 如果最终还是没找到文章,那说明无案可查,直接返回null
。$post = get_post( $post ); if ( ! $post ) { return null; }
简单来说,这段代码就是确保我们手里有一个有效的文章对象,没有文章,侦查个寂寞。
-
提取证据:
parse_blocks( $post->post_content )
这是最关键的一步!
parse_blocks()
函数负责把文章的内容($post->post_content
)分解成一个区块数组。 这个函数会扫描文章内容,找到那些符合区块格式的字符串,然后把它们解析成一个个独立的区块对象。$blocks = parse_blocks( $post->post_content ); if ( ! $blocks ) { return null; }
-
parse_blocks()
的工作原理 (简述)parse_blocks()
函数内部使用了正则表达式来匹配区块的开始和结束标记,然后提取区块的属性和内容。 区块的格式通常是这样的:<!-- wp:core/paragraph --> <p>这是一个段落。</p> <!-- /wp:core/paragraph -->
parse_blocks()
会识别<!-- wp:core/paragraph -->
这个标记,知道这是一个core/paragraph
类型的区块,然后提取<p>这是一个段落。</p>
作为区块的内容。如果文章内容不是标准的区块格式,
parse_blocks()
可能无法正确解析,返回一个空数组。
-
-
锁定嫌疑人:
$blocks[0]['blockName']
现在我们有了一个区块数组(
$blocks
)。get_post_block_type()
只关心第一个区块的类型,所以它直接访问$blocks[0]['blockName']
。blockName
属性存储了区块的类型(例如core/paragraph
、core/image
等)。if ( ! isset( $blocks[0]['blockName'] ) ) { return null; } return $blocks[0]['blockName'];
如果
$blocks
数组为空(说明文章里没有区块),或者第一个区块没有blockName
属性(这种情况不应该发生,除非区块数据损坏了),函数就返回null
。 -
宣布结果:
return $blocks[0]['blockName']
或return null
最后,函数把找到的区块类型(
$blocks[0]['blockName']
)返回。 如果没找到任何区块,或者文章内容为空,它就返回null
。
三、举几个栗子:实战演练
为了更好地理解 get_post_block_type()
的工作方式,咱们来模拟几种不同的文章内容,看看函数会返回什么。
文章内容 | get_post_block_type() 的返回值 |
说明 |
---|---|---|
<!-- wp:core/paragraph --><p>这是一个段落。</p><!-- /wp:core/paragraph --> |
core/paragraph |
文章开头是一个段落区块。 |
<!-- wp:core/image {"id":123,"url":"example.com/image.jpg"} --><img src="example.com/image.jpg" alt=""/> <!-- /wp:core/image --><!-- wp:core/paragraph --> |
core/image |
文章开头是一个图片区块。 |
这是一段普通的文本,不是区块。 |
null |
文章内容不是标准的区块格式,parse_blocks() 无法解析出任何区块。 |
` | null` |
文章内容为空。 | |
<!-- wp:core/paragraph --><p>这是一个段落。</p><!-- /wp:core/paragraph --><!-- wp:core/heading --><h2>这是一个标题</h2><!-- /wp:core/heading --> |
core/paragraph |
文章开头是段落,即使后面有标题,也只返回第一个区块的类型。 |
<!-- wp:acf/my-custom-block {"data":{"field_1":"value_1"}} /--> |
acf/my-custom-block |
文章开头是一个自定义区块(使用 ACF 创建的)。 |
<!-- wp:core/paragraph --><p>这是一个段落。</p><!-- /wp:core/paragraph --><!-- wp:missing/block --> |
core/paragraph |
即使有缺失的区块,仍然会提取第一个有效的区块。 |
四、parse_blocks()
:区块解析的核心
正如前面提到的,parse_blocks()
是 get_post_block_type()
的核心。 它负责把文章内容分解成区块数组。 虽然我们不会深入研究 parse_blocks()
的源码(因为它比较复杂),但了解它的基本原理非常重要。
parse_blocks()
主要做了以下几件事:
-
正则表达式匹配: 使用正则表达式找到文章内容中所有符合区块格式的字符串。 这些字符串通常以
<!-- wp:
开头,以<!-- /wp:
结尾。 -
提取区块名称: 从匹配到的字符串中提取区块的名称(例如
core/paragraph
、core/image
)。 -
提取区块属性: 有些区块有属性(例如图片的 URL、段落的对齐方式)。
parse_blocks()
会尝试从区块的开始标记中提取这些属性。 -
提取区块内容: 区块的内容是指位于开始标记和结束标记之间的 HTML 代码。
parse_blocks()
会把这些 HTML 代码提取出来,作为区块的内容。 -
创建区块对象: 把提取到的区块名称、属性和内容组合成一个区块对象,并添加到区块数组中。
五、使用场景:get_post_block_type()
能帮我们做什么?
get_post_block_type()
虽然简单,但在某些情况下非常有用。
-
判断文章是否使用了区块编辑器:
如果
get_post_block_type()
返回null
,说明文章内容可能不是用区块编辑器创建的,而是用经典编辑器或者其他方式创建的。$block_type = get_post_block_type(); if ( $block_type === null ) { echo '这篇文章可能不是用区块编辑器创建的。'; } else { echo '这篇文章是用区块编辑器创建的。'; }
-
根据第一个区块的类型执行不同的操作:
例如,如果文章的第一个区块是图片,你可以显示一个特殊的图片样式。
$block_type = get_post_block_type(); if ( $block_type === 'core/image' ) { echo '<div class="featured-image">'; the_post_thumbnail(); echo '</div>'; } else { the_content(); }
-
主题兼容性判断:
在主题开发中,可以根据文章的第一个区块类型来加载不同的样式表或者 JavaScript 文件,以确保主题与各种类型的区块兼容。
六、注意事项:get_post_block_type()
的局限性
get_post_block_type()
只是一个简单的函数,它有一些局限性。
-
只返回第一个区块的类型:
它不会告诉你文章里有多少个区块,也不会告诉你其他区块的类型。 如果你需要获取文章中所有区块的信息,你需要直接使用
parse_blocks()
函数,并遍历整个区块数组。 -
依赖于标准的区块格式:
如果文章内容不是标准的区块格式,
get_post_block_type()
可能无法正确解析。 例如,如果文章内容包含错误的 HTML 标签,或者区块的开始标记和结束标记不匹配,parse_blocks()
可能会返回错误的结果。 -
性能问题:
虽然
get_post_block_type()
本身很快,但parse_blocks()
函数可能会比较慢,特别是对于包含大量内容的文章。 如果你需要在循环中多次调用get_post_block_type()
,可能会影响网站的性能。 可以考虑使用缓存来优化性能。
七、高级技巧:自定义区块的识别
get_post_block_type()
可以识别 WordPress 内置的区块,也可以识别自定义的区块。 自定义区块通常使用 acf/
或者其他命名空间作为前缀。
例如,如果你使用 ACF(Advanced Custom Fields)创建了一个名为 my-custom-block
的区块,get_post_block_type()
会返回 acf/my-custom-block
。
你可以根据自定义区块的类型来执行不同的操作。
$block_type = get_post_block_type();
if ( $block_type === 'acf/my-custom-block' ) {
// 显示自定义区块的特殊样式
echo '<div class="my-custom-block-wrapper">';
// ...
echo '</div>';
}
八、总结:get_post_block_type()
的价值
get_post_block_type()
函数虽然简单,但它提供了一种快速判断文章是否使用区块编辑器,以及获取文章第一个区块类型的方式。 在主题开发、插件开发和自定义 WordPress 功能时,它可以帮助你更好地处理不同类型的文章内容。
记住,get_post_block_type()
只是一个工具,你需要根据具体的需求来选择合适的工具。 如果你需要更详细的区块信息,你应该直接使用 parse_blocks()
函数。
希望这次的讲座能帮助你更好地理解 get_post_block_type()
函数的工作原理和使用场景。 祝大家编程愉快!