Gutenberg RSS 区块(core/rss)完全解析:从 block.json 属性定义到服务端渲染的落地实现

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

导读

RSS 区块是 Gutenberg 块编辑器中用于聚合展示任意 RSS/Atom 订阅源条目的动态区块,广泛应用于资讯门户、博客聚合与内容推荐场景。本文以官方文档与仓库源码为准绳,完整拆解 core/rss 区块的属性体系、编辑器交互、服务端渲染调用链与测试验证方式,帮助读者在了解其配置方法的同时,掌握动态区块从元数据声明到最终 HTML 输出的完整工程实现。

区块概览:一个「零存储」的动态区块

依据 区块元数据,core/rss 区块的核心身份信息如下:

项目值
区块名称(Name)core/rss
标题(Title)RSS
分类(Category)widgets(小工具类)
API 版本3(apiVersion: 3)
区块类型动态区块(Dynamic,服务端渲染)
关键词(Keywords)atom、feed
说明Display entries from any RSS or Atom feed.

关键词 atom 与 feed 意味着在编辑器块插入器(Block Inserter)中,输入 "RSS"、"atom" 或 "feed" 均可检索到该区块。

该区块属于动态区块:它不在文章内容中保存最终的 HTML 片段,而是仅在数据库中持久化区块注释(Block Comment)与其 JSON 属性,每次页面请求时由服务端根据属性实时抓取并渲染订阅源条目。这种设计保证了订阅内容始终是最新的,也决定了其核心逻辑分布在前端 edit.jsx(编辑器体验)与 index.php(服务端渲染)两端。

Attributes 全属性清单与编辑器取值约束

属性(Attributes)在 block.json 的 attributes 字段中声明,是区块配置的「数据结构契约」。官方文档给出的完整属性表如下:

属性类型默认值说明
columnsnumber2网格布局时的列数
blockLayoutstring"list"布局方式,取值为 list(列表)或 grid(网格)
feedURLstring""订阅源地址;角色(Role)为 content,属于内容类属性
itemsToShownumber5展示的条目数量
displayExcerptbooleanfalse是否显示摘要
displayAuthorbooleanfalse是否显示作者
displayDatebooleanfalse是否显示发布日期
excerptLengthnumber55摘要最大单词数
openInNewTabbooleanfalse是否在新标签页打开链接
relstring—链接关系(Link Relation)属性值,无默认值

其中 feedURL 的 role: "content" 声明使其成为具有「内容角色」的属性——这意味着在多用户协作或某些同步场景下,该属性会被视为内容数据的一部分参与处理。

编辑器中的取值范围约束

官方文档只给出类型与默认值,而实际可配置范围定义在编辑器组件 edit.jsx 中,与 block.json 共同构成完整的参数约束:

  • Number of items(条目数):滑块范围 1~20(DEFAULT_MIN_ITEMS = 1、DEFAULT_MAX_ITEMS = 20),默认 5;
  • Max number of words in excerpt(摘要最大单词数):仅当「显示摘要」开启时出现,滑块范围 10~100,默认 55;
  • Columns(列数):仅当布局为「网格」时出现,滑块范围 2~6,默认 2。

各控件在 ToolsPanel(设置面板)中通过 ToolsPanelItem 组织,resetAll 回调(edit.jsx)会将上述属性一次性重置为默认值。值得注意的是,ToolsPanelItem 的 hasValue/onDeselect 逻辑保证了「设置被重置后控件折叠、再次变更后展开」的体验闭环。

Supports:区块支持的样式与功能特性

supports 属性同样定义于 block.json,官方文档列出的支持项如下:

  • anchor(锚点):true,可为区块设置 HTML 锚点 ID;
  • align(对齐):true,支持块级对齐;
  • html(HTML 编辑):false,禁止直接编辑原始 HTML(因为内容由服务端生成);
  • interactivity(交互性):clientNavigation: true,启用客户端导航支持,站点在前端无刷新跳转时区块可正常工作;
  • spacing(间距):margin 与 padding 均开启,可在设置面板中调整外边距与内边距;
  • color(颜色):background(背景)、text(文字)、gradients(渐变)、link(链接颜色)四项全部开启。

对照源码可以发现,block.json 中还额外声明了 __experimentalBorder(实验性边框):radius、color、width、style 均支持,可设置圆角、边框颜色、粗细与样式;同时 spacing.__experimentalDefaultControls 中 padding 与 margin 默认为关闭,避免在未显式配置时引入额外间距。以上支持项会通过 get_block_wrapper_attributes() 在服务端渲染时转化为 class 与 style 属性,从而让主题开发者可以用 CSS 变量或类名自由定制外观。

Block Markup:动态区块在文章内容中的持久化形态

由于是动态区块,core/rss 不会在 post content 中保存渲染后的 HTML。在数据库中,它仅保存为一行带 JSON 属性的块注释。官方文档给出的示例为:

<!-- wp:rss {"blockLayout":"grid","displayDate":true,"displayExcerpt":true,"displayAuthor":true,"excerptLength":20,"feedURL":"https://wordpress.org/news/","itemsToShow":4} /-->

这是一条自闭合(self-closing)块注释:区块名称为 wp:rss,大括号内为该次使用所定制的全部属性(覆盖了默认值)。WordPress 解析器在读取到该注释时,会调用 index.php 中注册的 render_callback,动态抓取 feedURL 指向的订阅源并输出完整列表 HTML。也正因如此,修改属性(如更换订阅源地址)后,前端展示会立即响应,而无需重新保存文章内容。

服务端渲染实现:index.php 的完整调用链

服务端渲染是 RSS 区块的「发动机」,全部逻辑位于 index.php 的 render_block_core_rss() 函数(自 WordPress 5.2.0 起提供),并通过 register_block_core_rss() 在 init 钩子上调用 register_block_type_from_metadata() 注册为 render_callback。

其执行流程可概括为以下六个阶段:

  1. 参数校验:读取 $attributes['feedURL'],若不存在或非字符串则直接返回空字符串;
  2. 循环自引用防护:若订阅地址去尾部斜杠后等于本站 site_url() 或 home_url(),则拒绝渲染并输出错误提示——将本站首页作为自己的 RSS 源会形成抓取循环拖慢站点,提示文案建议改用 Latest Posts(最新文章) 区块;
  3. 抓取与容错:调用 WordPress 的 fetch_feed() 抓取订阅源,返回 WP_Error 时输出 RSS Error: 及具体错误信息;当 get_item_quantity() 返回 0(源为空或已宕机)时输出「feed is down,请稍后重试」的占位错误;
  4. 条目遍历与拼装:通过 $rss->get_items( 0, $attributes['itemsToShow'] ) 截取前 N 条,对每条条目依次渲染标题、日期、作者、摘要:
    • 标题:先做 strip_tags + html_entity_decode + esc_html 清洗,为空则显示 (no title);随后用 esc_url 包裹为链接,并根据 openInNewTab 追加 target="_blank"、根据 rel 追加 rel="..." 属性;
    • 日期(displayDate 开启时):从条目取 Unix 时间戳,叠加 get_option( 'gmt_offset' ) 时区偏移后,用 date_i18n() 输出 datetime(ISO 8601)与站点 date_format 两种格式;
    • 作者(displayAuthor 开启时):读取作者对象名称,输出为 by {author} 样式的 wp-block-rss__item-author 标签;
    • 摘要(displayExcerpt 开启时):解码描述后经 wp_trim_words( $excerpt, $attributes['excerptLength'], ' [&hellip;]' ) 按单词数截断,并把可能的 [...] 统一替换为 [&hellip;];
  5. 容器类名计算:根据 blockLayout === 'grid' 添加 is-grid,网格时追加 columns-{n};根据日期/作者/摘要开关分别追加 has-dates、has-authors、has-excerpts,供主题样式钩取;
  6. 输出包装:get_block_wrapper_attributes() 合并区块支持生成的 class/style 后,以 <ul class="wp-block-rss ..."> 包裹全部 <li class="wp-block-rss__item"> 输出。

对应地,前端样式中 style.scss 使用 Flexbox 实现网格:.is-grid 下 li 默认占满整行,在 break-small 断点后按 columns-2 至 columns-6 计算宽度 calc((100% / N) - 1em),并让日期、作者等元信息以 display: block 的 0.8125em 小字号独立成行。

编辑器端体验:edit.jsx 的交互设计

编辑器的交互逻辑全部封装在 edit.jsx 的 RSSEdit 组件中,index.js 只负责注入图标(rss)、示例(example 演示属性指向 https://wordpress.org)并注册区块。

首次配置流程:当 feedURL 为空时组件进入编辑态,展示一个带 RSS 图标的 Placeholder,内含 URL 输入框与「Apply」按钮。提交时调用 prependHTTPS( feedURL ) 自动为缺失协议的地址补全 https://,确保服务端 fetch_feed() 拿到的始终是完整 URL。

工具栏(BlockControls):提供三个操作按钮——pencil(编辑 RSS URL,重新回到输入态)、list(列表视图)与 grid(网格视图),后两者通过写入 blockLayout 属性即时切换。

设置面板(InspectorControls):分两个分组——

  • 常规组使用 ToolsPanel 收纳「条目数量」「显示作者」「显示日期」「显示摘要」「摘要最大单词数(条件显示)」「列数(仅网格时显示)」「新标签页打开链接」等控件;
  • 高级组提供 rel(Link Relation)输入框,帮助文案引用 MDN 说明:rel 属性定义当前文档与链接资源之间的关系,最终由服务端拼接到每个条目的 <a> 标签上。

渲染预览:编辑器中通过 useServerSideRender 调用与前台完全一致的服务端渲染接口,实时取得渲染 HTML 并用 HtmlRenderer 呈现,实现「所见即所得」。渲染期间用 useDisabled 禁用预览区域避免误交互;status 为 loading 时显示 Spinner,error 时展示 Error: {message}。skipBlockSupportAttributes: true 则让预览阶段跳过区块支持的 class/style 注入,配合 editor.scss 中 .wp-block-rss .wp-block-rss { all: inherit; } 的重置规则,防止重复的内边距、边框等样式污染预览。

测试验证:渲染行为的自动化保障

仓库为 core/rss 提供了服务端渲染的单元测试 phpunit/blocks/render-block-rss-test.php,是理解其行为契约的可靠参考。该测试通过 pre_http_request 过滤器模拟 HTTP 请求,将 https://example.com/testrss.xml 的响应替换为测试夹具 feed-with-gmt-offset.xml,并关闭 feed 缓存(wp_feed_cache_transient_lifetime 返回 0)。

test_rss_date_rendering() 用例验证了日期渲染的两项关键契约(对应 ticket 66970 所修复的时区问题):将站点时区设为 UTC+9、日期格式为 F j, Y 后,断言渲染结果中包含 <time datetime= 元素、格式化日期 March 19, 2025,且 datetime 属性符合 ISO 8601 格式(2025-03-19)。这印证了 index.php 中「时间戳 + gmt_offset 偏移 + date_i18n 双格式输出」的实现逻辑。

实战建议:如何在自己的站点用好 RSS 区块

  1. 选择可靠的订阅源:feedURL 支持任意 RSS 2.0 / Atom 源;建议选择内容稳定、更新频繁的源,因为区块每次渲染都会实时抓取;
  2. 网格与列表按内容密度取舍:图文并茂的源适合 grid + 2~4 列;纯文字更新频繁的源更适合 list,避免视觉噪音;
  3. 开启摘要时控制单词数:excerptLength 建议保持在 20~55 之间,过长的摘要会破坏卡片式布局的整齐度;
  4. 新标签页与 rel 组合使用:开启 openInNewTab 后建议为 rel 填入如 nofollow、noopener 等值,兼顾站外跳转体验与 SEO/安全;
  5. 避免自引用循环:不要把本站首页地址填入 feedURL,服务端会直接拒绝渲染——聚合本站文章应改用 Latest Posts 区块;
  6. 定制外观:主题开发者可直接利用 wp-block-rss、is-grid、columns-N、has-dates 等类名编写样式覆盖,无需改动区块源码。

延伸阅读

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

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐