Commit Graph

2 Commits

Author SHA1 Message Date
浅念 f5dc2f7624 Task 15: product detail anchor tabs + per-product custom sections
User report: product detail page was wrong — section titles are
per-product custom data (CMS wppop_sections migration: Packing &
Delivery / Our Exhibition / Our Certifications / Our Company / FAQ),
not fixed headings; they must drive an anchor tab system like the
CMS [locale]/products/[slug].astro detailTabs.

Data side (both layers, task option 1 + 2):

- theme_pro.product_detail_sections: fields.sections
  [{title, content}] JSON is the structured source; legacy sync
  output that appended sections as trailing body H2 blocks is
  recognized by known/data titles and split out (overview keeps the
  rest; same-title blocks dedupe to the structured version; Features
  body block drops when fields.features renders it)
- sync_cms_data.build_product: store sections/features as structured
  fields JSON, stop appending H2 blocks to the body; stats now count
  entries with a sections field
- Specifications table no longer leaks structural JSON field keys
  (sections/features/specs/gallery/categories) — scalar spec keys
  only

Template side (trade-pro product.html, replaces 12a panel
switching):

- tab sequence is fully data-driven and matches the CMS: Product
  Details (always) -> custom sections (data titles) ->
  Specifications / Features (shown only when data exists)
- tabs are #anchor links, not panel toggles: all sections render
  flat with visible titles (readable and crawlable without JS; native
  anchor jump), JS adds smooth scrolling + scrollspy highlight +
  tab centering in the horizontal scroll row
- section ids are slug-derived (sec-packing-delivery), duplicate
  titles get an index suffix; features grid ports the CMS
  detail-feature-row

Tests: test_trade_pro_product_layout_structure rewritten for the
anchor-tab contract — sections via fields, legacy body-H2 fallback,
spec/features conditional tabs, no-sections product showing only
Product Details + Specifications, spec table free of JSON key leaks,
updated pro.css needles. 30 passed; the 1 failure
(test_trade_pro_blocks_visual_bridge) fails identically on the
previous commit (pre-existing, unrelated).

Co-Authored-By: Claude Code <noreply@example.com>
2026-10-29 13:49:08 +08:00
浅念 3ce4292794 Task 14: add CMS refined-data sync script (sync_cms_data.py)
Pull hesupipe published products/news/cases from the CMS control-api
public endpoints (the same refined data src/content/{products,news,cases}.ts
fetch at build time; those TS files are fetchers, not literal arrays) and
sync them into SiteForge entries via login + PATCH/POST:

- match by route slug (product /product/<slug>/, post keeps legacy WP
  route on update, slug-col truncation fallback), create when unmatched,
  never delete SiteForge-only entries
- port wp-text.ts cleaning (Gutenberg comments, [caption] -> figure,
  trailing form blocks, H1 -> H2, wrapInlineInP, excerpt) so bodies land
  sanitized (bleach on the API side strips aligncenter classes/styles)
- upload CMS media (/v1/media/... and local /images/ design fallbacks)
  through the SiteForge media API, rewriting body refs to media/<file>;
  per-target temp-dir cache dedupes uploads across runs
- product fields: color/standard/category + specs dict flattened into
  scalar keys (trade-pro Specifications table renders scalars only) +
  gallery as semicolon list; post fields: publish_date/category/tags;
  case fields: results/location/industry/gallery
- sync site name/tagline from site.ts SITE literal and set locale=en
  via PUT /api/i18n/sites/{id}/locale

Verified against a local uvicorn on a temp snapshot of the container DB:
52 products (47 updated + 5 created), 129 posts updated, 0 failures,
181 media covers, idempotent re-run, theme registry tests unchanged
(30 pass, 1 pre-existing failure).

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-29 12:05:57 +08:00