🐦 第3章 扣子插件和卡片
📄 一句话概括

从三条新闻到一张卡,三步:取数、排版、绑定。 三步里最容易错的是第三步——占位名打错一个字母,那个格子就永远空着。 这一节还把卡片的两个硬约束量出来:变量是白名单、行数有上限。

📝 本章和前面几章的关系

上一节讲卡片是什么,这一节做一个能用的。 这个案例在教材里是配套「最新头条新闻」的,做的事很简单:抓三条新闻,摆成一张卡, 底下放个「看更多」。 别小看它——第 8 章的推文生成器、第 12 章的海报助手,收尾那一步都是这个形状。

一、第一步:取数

三条新闻从哪来?平台上有现成的插件能干这件事(搜新闻、读网页),也可以自己写一个。 取回来的东西通常是一串条目,每条有标题、来源、时间、链接。 先确认字段名,因为下一步排版要按字段名取。 演示里造了三条,字段是 title、src、t。 真机上字段名可能是 title、source、pub_time,对不上就先映射一层。

二、第二步:排版

卡片里每一行显示什么,得先拼成字符串。比如「1. 标题(来源 时间)」。 这一步要盯的是字数。卡片一行放不下太多,标题太长会被截成两行加省略号。 演示里三条标题十三字左右,安全的。 真机上原标题往往三十字起步,排版时就得截断,别指望卡片自己处理。

所以这一步的产物不是「三条新闻」,是「三行已经排好版的字符串」。

三、第三步:绑定

模板里写 {{h}}、{{n1}}、{{n2}}、{{n3}},绑定时把四个变量填进去。 占位名必须一模一样。 模板写 {{n1}},绑定写 n_1,那个格子就空着,不报错。 演示里传了四个变量进去——n1、n2、n3 和一个多出来的 n4。结果只显示三条:模板里没有 {{n4}} 这个占位。

卡片的变量是白名单:模板里写了才填,多给的会被丢掉,也不会报错。这条规则反过来也成立: 模板里写了但你没给,就是空格子。

四、两个硬约束

约束一,变量白名单。 模板决定能填什么,不是数据决定。所以数据多一条,模板得先加一个占位。 约束二,行数上限。 卡片有最大高度。 三条两行标题加一个按钮差不多就满了,想放五条就得换成分页或者「看更多」。 这两个约束决定了卡片的做法:它是「定长」的,不是「自适应」的。数据量变化时你要自己处理, 卡片不会帮你。

所以做卡片之前先问:这份数据最多几条、每条最多几字。答不出来就先做纯文本。

五、渠道那一关

做完卡片,最后一步是在真渠道里看。公众号、飞书、网页支持的卡片类型不一样。 公众号这边通常只能用基础的文本与图文消息,复杂的列布局、颜色、按钮样式它会忽略或者报错。 飞书的卡片能力强很多,列、按钮、表单都能用。所以同一份内容,两个渠道要做两套模板。

这一条在教材里没有强调,但在实际项目里是第一号返工原因。先确认渠道支持什么,再画卡片。

六、动手 Demo:三条新闻,一张卡

三条新闻,一个列表壳加三个条目位。先正常渲染,再把三条改成四条看会发生什么。 每次都用「按元素拆行」的方式看结构——本沙箱没有渲染器。

TPL = {'type': 'column_set', 'columns': [
    {'type': 'column', 'elements': [
        {'type': 'text', 'content': '{{h}}'},
        {'type': 'text', 'content': '{{n1}}'},
        {'type': 'text', 'content': '{{n2}}'},
        {'type': 'text', 'content': '{{n3}}'},
        {'type': 'button', 'text': '看更多'},
    ]},
]}

var = {'h': '今日头条 · 三条'}
for i, it in enumerate(NEWS, 1):
    var['n%d' % i] = '%d. %s(%s %s)' % (i, it['title'], it['src'], it['t'])

c = card(TPL, var)      # 渲染
var['n4'] = '4. 多出来的一条'   # 多给一个变量
c4 = card(TPL, var)     # 第四条不会出现

实跑输出:

--------------------------------------------------------------------
卡片实战:把三条新闻摆成一张卡
--------------------------------------------------------------------


  ① 模板:一个列表壳 + 三个条目位
  --------------------------------------------------------------------
  今日头条 · 三条
  1. 国产大模型推理成本一年降了八成(科技日报 09:20)
  2. 某地试点公共数据授权运营(新华社 10:05)
  3. 开源社区发布新的向量检索库(GitHub 周报 11:40)
  [看更多]

  ② 三条太长会怎样
  --------------------------------------------------------------------
  卡片有行数上限。演示里三条标题只有十三字左右,真机上的原标题往往三十字起步。

| 来源 | 标题长度 |
|---|---:|
| 科技日报 | 15 字 |
| 新华社 | 12 字 |
| GitHub 周报 | 13 字 |

  三条各三十字,加上头部和按钮,一张卡纵向就撑满了。
  超出的部分会被截成两行加省略号——用户看到的是一条读不完的标题。
  所以卡片里一般只放「标题 + 来源 + 时间」,摘要留给点开之后。

  ③ 三条变四条
  --------------------------------------------------------------------
  传四个变量进去,渲染结果:
  今日头条 · 三条
  1. 国产大模型推理成本一年降了八成(科技日报 09:20)
  2. 某地试点公共数据授权运营(新华社 10:05)
  3. 开源社区发布新的向量检索库(GitHub 周报 11:40)
  [看更多]
  只出现了三条——模板里只有一个 {{n3}},你没加 {{n4}} 这个占位。
  ! 卡片的变量是「白名单」:模板里写了才会填,多给的会被丢掉,也不会报错。

  ④ 从数据到卡片的三步
  --------------------------------------------------------------------

| 步 | 做什么 | 要盯什么 |
|---:|---|---|
| 1 取数 | 插件或检索拿到原始条目 | 字段名与条数 |
| 2 排版 | 把条目拼成每一行要显示的字符串 | 字数上限 |
| 3 绑定 | 把字符串塞进模板的占位 | 占位名对得上 |

  三步里最容易错的是第三步:占位名打错一个字母,那个格子就永远空着。

①渲染出来是五行:头部、三条、一个按钮。这就是一张新闻卡在真机上的样子。 ②第二段量了一下三条标题的字数:十五、十二、十三。 演示里这个长度是安全的,真机上原标题往往三十字起步。 ③第三段最值得看:多给一个 n4,渲染结果还是三条。 模板里没有 {{n4}},多出来的变量被直接丢掉,不报错。 ④这就是卡片「定长」的本质:模板决定能填什么,不是数据决定。数据多一条,模板得先加一个占位。 ⑤最后那张三步表里,第一步盯字段名,第二步盯字数,第三步盯占位名。 三个地方各错一次,就是一整天的活。

30 秒实验

  1. 把你手上要展示的数据数一遍:最多几条、每条最多几字。超过卡片的容量就先做分页。
  2. 在公众号和飞书各发一次同一个卡片,对比哪些元素消失了。
  3. 检查一遍你所有卡片的占位名与绑定名,看有没有拼写不一致的。

常见误区

  1. 「数据有几条就填几条。」模板只有三个占位,第四条不会出现,也不会报错。
  2. 「标题长了卡片会自动换行。」会,但换到第二行之后开始截。排版时就该截断。
  3. 「平台预览通过就能上线。」不同渠道支持的类型不一样。公众号对复杂布局基本不认。
自测三问(点开对答案) 1. 从数据到卡片有哪三步? —— 取数、排版、绑定。三步分别盯字段名、字数、占位名。 2. 为什么多传一个变量,卡片不会报错? —— 因为变量是白名单:模板里写了才填,多给的直接丢掉。反过来,模板写了没给值就是空格子。 3. 卡片的两个硬约束是什么? —— 变量白名单、行数上限。它们决定了卡片是「定长」的,数据量变化要你自己处理。

插件和卡片都过了,下一章进这本书的骨头:工作流。 先看它是什么图、分几类,再看十五个节点各自管什么——这一章值得读两遍。

相关笔记