Dawn 邮件订阅、商品徽章与评分星:表单与卡片实现
本文基于 Dawn v15.3.0,源码固定到 ecb06c3(核验于 2026-09-29)。结论限于此提交,不表示其他版本行为相同;本篇为静态源码分析,未完成店铺运行验证。Dawn 上游已发布 v16.0.0(2026-08-10,GitHub Releases 核对),本库 Dawn 正文统一以 v15.3.0 为基线,升级前需重新核对。
对应哪些通用模式
覆盖订阅获取模块与 Inline Form(邮件订阅表单)、Badge(商品卡与价格里的标签)、评价展示模块中的星级部分。Dawn 没有内置评价列表、订阅弹窗与百分比折扣标签,后文逐项给出搜索依据。商品卡整体结构不在本篇范围,商品页整体见 Dawn 架构。
入口与文件
| 文件 | 职责与输出条件 |
|---|---|
| sections/newsletter.liquid | 独立订阅分区,块:heading、paragraph、email_form(各限 1)与 @app;有 preset,disabled_on 页头组;默认模板未使用 |
| sections/email-signup-banner.liquid | 带背景图的订阅横幅,enabled_on 仅 password 模板;templates/password.json 默认使用 |
| sections/footer.liquid | 页脚内联订阅,newsletter_enable(默认 true)与 newsletter_heading;页脚组默认开启 |
| snippets/card-product.liquid | 商品卡:card__badge(售罄 / 折扣)与评分星(show_rating) |
| snippets/price.liquid | 价格块内的 Sale / Sold out 徽章(show_badges),商品页使用 |
| sections/main-product.liquid | 商品页 rating 块(不在默认 product.json 中);价格块 show_badges: true |
| assets/component-rating.css、assets/component-price.css、assets/component-card.css | 星级绘制、价格徽章显隐、徽章在卡片中的位置 |
数据从哪来
订阅表单。 三处都是 Liquid form 'customer' 标签,字段为 contact[email] 与隐藏字段 contact[tags](值 newsletter);成功与错误依赖 form.posted_successfully? 和 form.errors(错误文本取 form.errors.translated_fields.email 与 form.errors.messages.email);文案来自 newsletter.label、newsletter.button_label、newsletter.success。提交后客户记录与营销同意状态由平台处理,主题源码中没有同意字段,未核验。
徽章。 卡片用商品级数据:card_product.available == false 显示 products.product.sold_out;card_product.compare_at_price > card_product.price 且可售显示 products.product.on_sale(英文文案 Sold out、Sale)。价格块(商品页)用所选变体:price--sold-out / price--on-sale 类由 compare_at_price > price 与 available 决定,CSS 控制两个徽章显隐。徽章位置 badge_position、圆角 badge_corner_radius、颜色方案 sale_badge_color_scheme、sold_out_badge_color_scheme 来自主题设置(config/settings_schema.json)。
评分。 读取 product.metafields.reviews.rating.value(.rating、.scale_max)与 metafields.reviews.rating_count;schema 的 info 文案写明需要应用提供评分。元字段为空时整块不输出。
交互怎样运行
订阅表单没有专属 JS:rg 在 assets/*.js 中搜 newsletter、contact[tags] 无命中,提交是整页表单提交,成功或失败由重新渲染的页面呈现。输入框有 required、aria-required、autocomplete="email";出错时输入框 autofocus、aria-invalid="true" 并以 aria-describedby 指向错误文案;成功时渲染 h3[tabindex="-1"][autofocus]。Liquid form 标签渲染出的 action 与锚点未核验。
徽章与评分星均为服务端输出,无 JS。星级用 CSS:.rating-star::before 填入 ★★★★★,以 linear-gradient 与 --rating、--rating-max、--rating-decimal 计算填充比例;小数部分 0.3 至 0.7 记半星,大于 0.7 记一星,--rating 取 floor。商品页价格块带 role="status",变体切换时 product-info 替换其 innerHTML(见 Dawn 商品媒体中同一条更新链)。
与通用契约的一致与差距
| 通用要求 | Dawn 现状 |
|---|---|
| Inline Form:标签、错误与字段关联 | 有可见 label 与 placeholder 同文(「Email」);提交按钮仅图标,名称在 aria-label(「Subscribe」);错误与输入框关联 |
| 成功 / 错误明确、失败保留输入 | 成功文案「Thanks for subscribing」;出错时输入框 value 取 form.email 回填;只处理 email 字段错误 |
| 无 JS 退化 | 天然可用(原生表单提交),但没有异步提交与「提交中」状态 |
| 说明用途、同意与退出方式 | 全仓库未找到订阅用途、同意或隐私文案(搜索词:consent、accepts_marketing、marketing、privacy、gdpr,仅命中语言文件中的 URL 文本);paragraph 块可由商家自行写说明 |
| 同页多个表单 | 三处表单的提交按钮都写死 id="Subscribe",同页出现页脚与订阅分区时 id 重复 |
| 订阅弹窗与触发规则 | 在固定提交的全仓库搜索中未找到订阅弹窗或触发 / 频次逻辑(搜索词:newsletter、subscribe、form 'customer'、contact[tags];订阅表单仅上述三处,主题里的模态组件使用者为商品弹窗块、商品卡快速加购与批量、collage、页头搜索,均无订阅) |
| Badge 有规则、数量少、优先级 | 每卡最多一个:售罄优先于折扣(if / elsif);规则是「所有变体不可售」与「最低对比价高于最低价」,不涉及新品或畅销 |
| Badge 不只靠颜色 | 徽章是文字标签;卡片链接的 aria-labelledby 同时引用标题与徽章 id。文字对比度取决于商家选的颜色方案,未核验 |
| 折扣百分比 | 在固定提交的全仓库搜索中未找到折扣百分比徽章(搜索词:percent、discount,命中仅为图片比例、动画与购物车折扣行);只有文字 Sale,商品页价格块另显示划线价。搜索 badge 得到的全部类型:Sale、Sold out、文章卡 Blog、搜索结果 Page、礼品卡过期、媒体缩略图的 3D / 视频图标;没有新品或畅销徽章 |
| 评分星的文字等价 | 容器 role="img" 加 aria-label(「X out of Y stars」),星星 aria-hidden,评价数有视觉隐藏文字。但 .rating-text(「4.5 / 5」)默认 display:none,仅强制颜色模式显示;空星为前景色 15% 透明度,对比度未核验 |
| 评价列表、分布、筛选 | 在固定提交的全仓库搜索中未找到评价列表、评分分布或筛选(搜索词:review、reviews(按词匹配)、comment,仅命中评分元字段、total_reviews 文案与文章评论)。main-article 有博客文章评论(new_comment),与商品评价无关 |
| 评分与评论的来源一致 | 仅汇总评分与数量,依赖外部应用写入元字段;structured_data 过滤器(商品页 JSON-LD)是否输出评分字段不在主题源码中,未核验 |
定制入口与风险
商家可调:页脚 newsletter_enable / newsletter_heading;订阅分区的标题、说明、颜色方案、full_width、上下内边距;徽章位置、圆角与两个颜色方案;在集合网格、特色集合、相关商品、搜索分区勾选 show_rating(默认模板里均为 false),商品页与特色商品添加 rating 块。开发者改动的耦合点:三份表单近乎复制,改一处需同步其余;同步修复 id="Subscribe" 重复;徽章逻辑在 card-product 里输出两处(card_style 不同时由 component-card.css 的规则显隐其一)、在 price.liquid 一处,新增徽章类型要同时改;评分依赖 reviews 命名空间,换评价应用时先确认它是否写入同一元字段。
建议的验证范围
本篇均未执行:
- 提交有效邮箱、空值与非法邮箱,检查成功 / 错误呈现、焦点位置与回填,并在后台确认客户与
newsletter标签。 - 页面同时含页脚与订阅分区时,检查重复
id的实际影响。 - 准备全部变体售罄、部分售罄、有 / 无对比价的商品,核对卡片与商品页徽章及变体切换后的价格块。
- 安装并配置评价应用后,检查元字段、卡片与商品页星级、半星取整与屏幕阅读器读法;无评价数据时确认整块不输出。
- 强制颜色与高对比模式下核对评分显示。