Files
cms-SiteForge/themes/trade-pro/pages/article.html
T
浅念 598f4695dd feat: port cms article detail layout into trade-pro + review minors
- article hero/meta/rich-body/author card/next-story/related sidebar
  per cms news/[slug] design; .pro-article-hero contract preserved
- review minors: back-link & CTA render even with 1-2 posts only;
  specificity comment notation corrected to (0,3,1)/(0,2,1)

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

92 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 or tp_next %}
<section class="section section--soft sf-tp-article-related">
<div class="wrap sf-tp-article-side">
{% if tp_related %}
<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>
{% endif %}
<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 %}