news 2026/9/17 22:56:47

Gutenberg core/read-more 块深度解析:服务端渲染的“阅读更多“链接块

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Gutenberg core/read-more 块深度解析:服务端渲染的“阅读更多“链接块

Gutenberg core/read-more 块深度解析:服务端渲染的""链接块

【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenberg

core/read-more 是 Gutenberg(WordPress 块编辑器项目)内置的主题类动态块,用于在文章列表、查询循环等场景中展示指向文章、页面或其他内容类型的""链接。本文以 read-more 块官方文档 为主体骨架,结合该块在仓库中的 block.json、服务端渲染实现 与 编辑端组件 源码,完整解析其属性定义、支持能力、渲染原理与编辑器交互,读完即可在自己的主题或块开发中精准使用并二次扩展该块。

一、块概览:一个纯服务端渲染的动态块

按官方文档的块 API 定义,core/read-more具有以下注册元信息:

项目
块名称(Name)core/read-more
分类(Category)theme(主题类)
API 版本(API Version)3
块类型(Block Type)Dynamic(动态块,服务端渲染)

该块属于动态块(Dynamic Block):它由服务器在渲染时生成最终 HTML,而不会把静态 HTML 保存进文章内容。这也决定了它通常在**查询循环(Query Loop)**等模板块内部被反复渲染——每次渲染时根据当前上下文中提供的postId动态生成指向对应文章的链接,实现"一篇文章一个链接"的效果。

二、块注册与元数据:block.json 如何定义该块

与 Gutenberg 中所有通过register_block_type_from_metadata注册的块一致,core/read-more的块元数据集中在 block.json:

{ "$schema": "https://schemas.wp.org/trunk/block.json", "apiVersion": 3, "name": "core/read-more", "title": "Read More", "category": "theme", "description": "Displays the link of a post, page, or any other content-type.", "textdomain": "default", "attributes": { "content": { "type": "string", "role": "content" }, "linkTarget": { "type": "string", "default": "_self" } }, "usesContext": [ "postId" ], "supports": { "anchor": true, "html": false, "color": { "gradients": true, "text": true }, "typography": { "fontSize": true, "lineHeight": true, "__experimentalFontFamily": true, "__experimentalFontWeight": true, "__experimentalFontStyle": true, "__experimentalTextTransform": true, "__experimentalLetterSpacing": true, "__experimentalTextDecoration": true, "__experimentalDefaultControls": { "fontSize": true, "textDecoration": true } }, "spacing": { "margin": [ "top", "bottom" ], "padding": true, "__experimentalDefaultControls": { "padding": true } }, "__experimentalBorder": { "color": true, "radius": true, "width": true, "__experimentalDefaultControls": { "width": true } }, "interactivity": { "clientNavigation": true } }, "style": "wp-block-read-more" }

几个关键点:

  • 注册入口:PHP 侧通过register_block_type_from_metadata( __DIR__ . '/read-more', ... )以目录方式加载元数据,见 index.php,并挂载在init钩子上;JS 侧则通过 init.js 调用 index.js 中的init()完成编辑端注册。
  • 样式句柄"style": "wp-block-read-more"对应 style.scss,该样式由构建流程编译后随块按需加载。
  • html: false:禁止用户直接在代码编辑器中书写原始 HTML,保证该块的输出完全由服务端渲染逻辑控制。

三、属性(Attributes)详解

官方文档给出的属性定义(定义于 block.json 的attributes属性中):

属性类型默认值说明
contentstring角色(Role)为content,即块的内容文本
linkTargetstring"_self"链接的打开方式(target属性值)

3.1 content:链接文字

content是块的内容角色属性,存的是""链接上显示的文字。它有两个特殊之处:

  1. 默认回退:当content为空时,服务端渲染会回退到默认文案Read more(本地化字符串,见下文渲染实现);
  2. 富文本编辑:在编辑器中它不是普通文本框,而是RichText组件渲染的可直接编辑链接文字(见 edit.jsx),且设置了withoutInteractiveFormatting禁用链接内部的内联格式。

3.2 linkTarget:链接打开方式

linkTarget的默认值是"_self"(当前窗口打开)。编辑器侧通过设置面板(Inspector Controls)中的Open in new tab开关控制:开启时设为"_blank",关闭时重置为"_self",见 edit.jsx。

在 PHP 渲染时该值会被写入<a>标签的target属性:

esc_attr( $attributes['linkTarget'] )

完整代码见 index.php。

四、支持能力(Supports):样式与布局的可定制范围

Supports 定义于 block.json 的supports属性中,官方文档列出的能力如下:

  • anchortrue——允许为该块设置 HTML 锚点(id属性),便于页内锚点跳转。
  • htmlfalse——不支持原始 HTML 编辑。
  • colorgradients: truetext: true——支持渐变背景与文字颜色(注意:这里未开放背景纯色,仅开放了渐变与文字色)。
  • typographyfontSizelineHeighttrue;同时开启了实验性排版能力__experimentalFontFamily(字体)、__experimentalFontWeight(字重)、__experimentalFontStyle(样式)、__experimentalTextTransform(大小写转换)、__experimentalLetterSpacing(字距)、__experimentalTextDecoration(文本装饰),默认控制项为fontSizetextDecoration
  • spacingmargin仅开放topbottom两个方向;paddingtrue全方向开放,默认控制项为padding
  • interactivityclientNavigation: true——支持客户端导航(在站点编辑/前台交互式导航中平滑切换页面,避免整页刷新)。

需要说明的是,block.json 中还额外配置了__experimentalBorder(颜色、圆角、宽度,默认控制项为width),这一项属于块元数据中的实验性支持,编辑器据此在样式面板中渲染对应的边框控制项。这些能力共同决定了用户在编辑器"样式"侧栏里能看到哪些定制选项。

五、上下文(Context):块如何拿到 postId

core/read-more通过usesContext: [ "postId" ](见 block.json)消费由外层块提供的postId上下文。

官方文档的 Context 一节明确指出其唯一依赖的上下文是postId。这也解释了为什么该块脱离查询循环等提供postId的容器时无法渲染——服务端渲染函数在拿不到postId时会直接返回空字符串:

if ( ! isset( $block->context['postId'] ) ) { return ''; }

见 index.php。因此它的典型宿主是查询循环(Query Loop)块文章列表模板:外层块遍历文章并下发postIdread-more块随即为每一篇文章生成对应链接。

六、服务端渲染实现:render_block_core_read_more 全流程

动态块的核心逻辑在 index.php 的render_block_core_read_more( $attributes, $content, $block )函数中,自 WordPress 6.0.0 起提供。完整流程如下:

  1. 上下文校验:若$block->context['postId']不存在则返回空字符串(不输出任何 HTML)。
  2. 获取文章标题get_the_title( $post_ID )取文章标题;若标题为空,则回退为本地化文案untitled post %s%s为文章 ID),用作无障碍描述。
  3. 构造屏幕阅读器文本:以: %s%s为文章标题或 ID)拼出screen-reader-text内容,保证读屏软件能说清楚"这个链接指向哪篇文章"。
  4. 计算对齐类名:若存在justifyContent属性,则附加is-justified-{value}类(对应查询循环中对齐设置)。
  5. 获取包装属性get_block_wrapper_attributes()生成classid(锚点)、内联样式等包装属性,最终输出到<a>标签上。
  6. 确定链接文字$more_text优先使用content属性(经wp_kses_post过滤),为空时回退到本地化文案Read more
  7. 输出链接
return sprintf( '<a %1$s href="%2$s" target="%3$s">%4$s<span class="screen-reader-text">%5$s</span></a>', $wrapper_attributes, esc_url( get_the_permalink( $post_ID ) ), esc_attr( $attributes['linkTarget'] ), $more_text, $screen_reader_text );

可见最终生成的 HTML 结构是:带包装属性(类名、锚点、样式)的<a>标签,href指向get_the_permalink( $post_ID )返回的文章永久链接,targetlinkTarget决定,内部依次是可见链接文字和仅供读屏软件识别的screen-reader-text补充说明。所有输出均经过esc_url/esc_attr/wp_kses_post转义,保证了 XSS 安全性。

注册部分通过init钩子完成:

function register_block_core_read_more() { register_block_type_from_metadata( __DIR__ . '/read-more', array( 'render_callback' => 'render_block_core_read_more', ) ); } add_action( 'init', 'register_block_core_read_more' );

七、编辑器交互:富文本直改 + 设置面板

编辑端组件位于 edit.jsx,由ReadMore函数组件实现,包含两大块:

1. 设置面板(InspectorControls):使用__experimentalToolsPanel/ToolsPanelItem组件构建"设置"面板,其中唯一的控制项是Open in new tab开关(ToggleControl)。开关状态由linkTarget === '_blank'决定,切换时在'_blank''_self'之间写入linkTarget;面板的"重置全部"动作会把linkTarget重置回_self

2. 富文本编辑区:使用RichText组件直接渲染块主体,tagName="a"使其在编辑器中即以链接形态呈现,placeholderRead morevalue绑定content属性,onChange同步写回。同时配置了__unstableOnSplitAtEnd:当光标在末尾回车拆分块时,会在其后插入默认块(createBlock( getDefaultBlockName() )),延续 Gutenberg 块编辑器的拆分交互习惯。

块图标取自@wordpress/iconslink图标,并在 index.js 中提供了一个example示例(content: 'Read more'),供块目录与预览场景使用。

八、样式与可访问性设计

style.scss 定义了wp-block-read-more的前台样式:

.wp-block-read-more { display: block; width: fit-content; &:where(:not([style*="text-decoration"])) { text-decoration: none; &:focus, &:active { text-decoration: none; } } }

设计要点:

  • display: block配合width: fit-content,使链接块按内容收缩宽度、独立成行,便于在文章列表中垂直排布;
  • 通过:where(:not([style*="text-decoration"]))只在用户未通过排版设置显式指定文本装饰时去掉下划线,避免覆盖用户的样式面板配置;
  • 服务端渲染中嵌入的screen-reader-text为链接补充了"指向哪篇文章"的无障碍信息,是对可访问性的显式支持(屏幕阅读器用户能听到例如 "Read more: 我的文章标题")。

九、动态块的内容存储格式

因为这是动态块,文章内容中不会保存最终 HTML,只保存块注释标记:

<!-- wp:read-more /-->

从官方文档的 Block Markup 一节可知,该块在文章内容中以自闭合块注释形式存储(无属性的默认形态)。如果设置了属性,则会以 JSON 形式内联在注释中,例如:

<!-- wp:read-more {"content":"继续阅读","linkTarget":"_blank"} /-->

实际渲染时由 PHP 服务端根据注释中的属性与上下文中的postId实时生成链接。这意味着即便文章标题后续发生变化,链接指向也不会失效;但同时也意味着前台必须经过 WordPress 渲染管线才能得到最终 HTML。

十、典型应用场景与扩展方向

综合源码实现,core/read-more块最典型的落地场景是:

  1. 查询循环(Query Loop)模板:在文章卡片布局中放置该块,自动为循环内每篇文章生成""链接——这正是它通过usesContext: postId消费上下文的设计初衷;
  2. 首页/归档页的自定义文章列表:与latest-postspost-excerpt等块组合使用(这些块在 block-library 源码 中同样引用read-more相关渲染逻辑),构成"摘要 + "的经典卡片结构;
  3. 多语言与品牌化定制:通过content属性替换默认的Read more文案,例如改为"继续阅读"、"查看详情"等,配合linkTarget决定是否新窗口打开。

若需在自有主题中复刻该块的注册方式,可直接参考 index.php 的register_block_type_from_metadata+render_callback模式,将block.jsonsupportsattributesusesContext的配置迁移到自定义块中,即可获得与本块一致的编辑器体验与渲染行为。

参考资料

  • read-more 块 API 文档
  • block.json 元数据定义
  • 服务端渲染实现 index.php
  • 编辑端组件 edit.jsx
  • 块入口与注册 index.js、init.js
  • 前台样式 style.scss

【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenberg

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 22:56:41

5G小区高负荷判定:从PRB利用率到RRC用户数的联合门限解析

简介&#xff1a;5G高负荷场景流量与用户数联合判定标准文档&#xff0c;面向通信网络工程师、5G无线优化人员及运营商网络规划运维者&#xff0c;用于解决高负荷小区识别、容量评估与扩容决策等问题。内容给出大、中、小数据包划分依据&#xff0c;并覆盖2.6G/4.9G/700M等频段…

作者头像 李华
网站建设 2026/9/17 22:56:15

C++指针冒泡排序:从底层原理到代码调试的完全指南

如果你正卡在“C入门练习题里的指针冒泡排序”上&#xff0c;这篇笔记应该能帮到你。作为C入门阶段最常被拿来练手的组合题&#xff0c;指针和冒泡排序绑在一起&#xff0c;难度其实没有想象中那么高&#xff0c;但它确实是检验你三样基本功够不够扎实的好题目&#xff1a;指针…

作者头像 李华
网站建设 2026/9/17 22:55:59

准确率98%却零召回:混淆矩阵与精确度召回率实战

评估报告上写着 accuracy 0.983&#xff0c;评审会上没人提异议&#xff0c;模型顺利上线。三周之后业务方找过来&#xff0c;说这套风控规则"一个坏账都没拦住"。回头翻评估日志才发现&#xff0c;测试集里坏样本只占 1.7%&#xff0c;模型把所有样本都判成了"…

作者头像 李华
网站建设 2026/9/17 22:53:07

Open Agents提示词缓存:如何降低50%以上的AI API成本

Open Agents提示词缓存&#xff1a;如何降低50%以上的AI API成本 【免费下载链接】open-agents An open source template for building cloud agents. 项目地址: https://gitcode.com/GitHub_Trending/op/open-agents Open Agents 是一个用于构建云端编程 Agent 的开源模…

作者头像 李华
网站建设 2026/9/17 22:52:28

嵌入式学员项目实战:任务拆解、环境搭建与评审标准

1. 验收现场最常出现的尴尬&#xff1a;能演示&#xff0c;但答不出为什么带过几批嵌入式学员之后&#xff0c;我总结出一个特别扎心的规律&#xff1a;板子跑起来了&#xff0c;灯亮了&#xff0c;屏幕上数字跳了&#xff0c;但只要问一句"你这个串口为什么用DMA而不是中…

作者头像 李华