Files
cms-SiteForge/themes/trade-pro/pages/article.html
T
浅念 1eddcf9136 feat: port cms article detail layout into trade-pro (hero/body/related)
Task 10d: rewrite trade-pro article.html from the thin pro-article
skeleton to the cms news/[slug].astro design (pixel baseline
dist/hesupipe/en/news/<slug>/):

- hero reuses the 10c sf-tp-page-hero component (cover as bg image +
  brand-soft overlay) with the breadcrumb inside; the platform contract
  class .pro-article-hero stays on the hero section and the pro-base
  centered/giant-h1 skeleton is flattened by specificity in pro.css
- meta row (category pill - publish_date - author), rich-text body via
  body_copy with a cms rich-body typographic layer, divider, author
  card, next-story navigation
- related band below the content: More News side box (120px thumb rows,
  3 items, self and next-story excluded) + dark side CTA + back link,
  1fr+300px grid collapsing at 900/620
- date field is meta.fields.publish_date (blueprints post definition),
  rendered raw as YYYY-MM-DD
- new responsive rules live in the 10d media blocks appended at the end
  of pro.css to avoid the 10c source-order cascade trap; the 620 hero
  h1 compact size is re-declared at the same specificity because the
  10d no-media h1 reset (0,4,0) outranks the 10c 620 rule (0,3,0)
- tests: test_trade_pro_article_layout_structure builds a site with a
  cover/date/rich-body post plus 4 other posts and asserts hero/meta/
  body/author/next/related structure, .pro-article-hero presence, no
  bare arrow characters

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-23 15:04:07 +08:00

90 lines
5.3 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{# trade-pro article detail — cms 文章详情设计移植(Task 10d)。
区块序列对照 D:/project/cms/runtimes/astro-site-runtime/src/pages/[locale]/news/[slug].astro
(像素基准 dist/hesupipe/en/news/<slug>/):
面包屑(hero 顶部)→ PageHero(眉题=分类 / h1 / 导语 / 封面底图 + brand-soft 罩)
→ meta 行(分类胶囊 · 发布日期 · 作者)→ 富文本正文 → 分隔线 → 作者卡
→ 下一篇导航 → More News 相关盒(120px 缩略图 + 分类 + 标题)+ 深色侧栏
CTA + 返回列表(1fr + 300px 双列带)。
与 cms 的结构决策:
1. .pro-article-hero 平台契约类保留挂在 hero 上(test_theme_pro_v3 对所有
主题 article 页断言该类存在);pro-base 骨架的居中排版与巨型 h1 由
pro.css 的 article 作用域规则按特异性压平。
2. cms 的“下一篇”按全量列表顺序取模回绕、相关阅读同 tag 优先补位;
平台 groups['post'] 无稳定语义顺序,简化为:下一篇 = 排除自身后首条,
相关盒 = 其余文章取 3(与下一篇去重,小数据集不出现重复链接)。
3. 日期字段是 meta.fields.publish_date(blueprints 为 post 定义的发布日期
字段),YYYY-MM-DD 原串直出(cms 同款,不做本地化重排);作者缺省回落
“{site.name} Editorial Team”(cms 的 HESU Team 位)。
4. cms 正文区分富文本/纯文本双通道(纯文本首段 lead-para 放大);平台正文
统一走 body_copy(.pro-rich 基线 + pro.css 的 sf-tp-article-body 排版层),
无纯文本分支。
5. 页尾 CTA 横幅由 pro.html 的 .pro-end-cta 承担,cms 的 Cta 组件不重复。 #}
{% set tp_others = groups['post']|rejectattr('route','equalto',page.route)|list %}
{% set tp_next = tp_others[0] if tp_others else none %}
{% set tp_related = tp_others[1:4] %}
<section class="sf-tp-page-hero sf-tp-article-hero pro-article-hero">
{% if page.cover %}<img class="sf-tp-page-hero-bg" src="{{ safe_image(page.cover) }}" alt="" width="1600" height="900" fetchpriority="high" decoding="async">{% endif %}
<div class="sf-tp-page-hero-overlay" aria-hidden="true"></div>
<div class="wrap">
<nav class="sf-tp-breadcrumb sf-tp-article-breadcrumb" aria-label="Breadcrumb" data-reveal>
<a href="/">Home</a><a href="/news/">News</a><span class="sf-tp-breadcrumb-current">{{ page.title }}</span>
</nav>
<div class="sf-tp-page-hero-copy" data-reveal style="--reveal-i: 1">
<span class="eyebrow">{{ fields.get('category') or 'NEWS & INSIGHTS' }}</span>
<h1>{{ page.title }}</h1>
{% if page.summary %}<p class="sf-tp-page-hero-lead">{{ page.summary }}</p>{% endif %}
</div>
</div>
</section>
<article class="section sf-tp-article-content">
<div class="wrap">
<div class="sf-tp-article-meta" data-reveal>
<span class="sf-tp-tag">{{ fields.get('category') or 'News' }}</span>
{% if fields.get('publish_date') %}<span class="sf-tp-article-meta-dot" aria-hidden="true">·</span><time datetime="{{ fields.get('publish_date') }}">{{ fields.get('publish_date') }}</time>{% endif %}
<span class="sf-tp-article-meta-dot" aria-hidden="true">·</span>
<span>{{ fields.get('author') or (site.name ~ ' Editorial Team') }}</span>
</div>
<div class="sf-tp-article-body" data-reveal>{{ body_copy(content, page) }}</div>
<div class="sf-tp-article-divider" aria-hidden="true"></div>
<footer class="sf-tp-article-foot">
<div class="sf-tp-article-author">
<div class="sf-tp-article-avatar" aria-hidden="true">{{ (site.name or 'S')[:1]|upper }}</div>
<div>
<strong>{{ fields.get('author') or (site.name ~ ' Editorial Team') }}</strong>
<span>{{ (footer_text or site.tagline or 'Industry insights and company news from our team.')|truncate(80, True, '…') }}</span>
</div>
</div>
</footer>
{% if tp_next %}
<a class="sf-tp-next-story" href="{{ safe_href(tp_next.route) }}" data-reveal>
<span class="sf-tp-next-story-label">Next story</span>
<span class="sf-tp-next-story-title">{{ tp_next.title }} {{ icon('arrow-right', cls='sf-tp-icon--sm') }}</span>
</a>
{% endif %}
</div>
</article>
{% if tp_related %}
<section class="section section--soft sf-tp-article-related">
<div class="wrap sf-tp-article-side">
<div class="sf-tp-article-side-box" data-reveal>
<h3>More news</h3>
{% for p in tp_related %}
<a class="sf-tp-article-side-item" href="{{ safe_href(p.route) }}">
<div class="sf-tp-article-side-media sf-tp-card-media">{{ cover(p, 'post') }}</div>
<div class="sf-tp-article-side-text">
<span class="sf-tp-article-side-tag">{{ fields_of(p).get('category') or 'News' }}</span>
<span class="sf-tp-article-side-title">{{ p.title }}</span>
</div>
</a>
{% endfor %}
</div>
<div class="sf-tp-article-side-cta" data-reveal style="--reveal-i: 1">
<span class="eyebrow">{{ site.name }}</span>
<h3>Ready to source with confidence?</h3>
<a class="sf-tp-btn" href="/contact/">Get a quote {{ icon('arrow-right') }}</a>
</div>
<a class="sf-tp-article-back" href="/news/">{{ icon('arrow-left', cls='sf-tp-icon--sm') }} Back to news</a>
</div>
</section>
{% endif %}