睿能科技
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

17 KiB

EN Demo UI i18n Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Make website/1/en/demo hardcoded UI English, and make shared JS show zh/en copy from a lightweight t() dictionary based on URL language.

Architecture: Add getUiLang() + t(key, vars?) + a zh/en map in common.js (exposed on window). Replace user-visible Chinese in shared JS with t(). Translate EN demo HTML/static strings in place. Leave comments and CMS-bound fields alone.

Tech Stack: ThinkPHP theme HTML, shared Vite-built static JS under public/themes/dist_static/static/js/, existing URL lang prefix (/en/...).

Spec: docs/superpowers/specs/2026-09-07-en-demo-ui-i18n-design.md

Global Constraints

  • Translate user-visible hardcoded UI only (not code comments).
  • Do not translate CMS/tag output ({$vo.title}, nav titles from backend, etc.).
  • Do not modify website/1/zh/demo/ templates for copy (shared JS only, bilingual).
  • Do not translate SVG internal id="矢量…" / id="微信 1" attributes (not user-visible).
  • Brand in EN UI: RAYNEN / Raynen Technology.
  • Currency wording in EN: use Yuan (e.g. footer unit text).
  • UI lang: first path segment enen, else zh (same as header EN/CN mapping).
  • Missing t key: return zh string if present, else the key; never throw.
  • Verification is grep + manual smoke (no PHPUnit/Jest in this theme path).

File map

File Responsibility
public/themes/dist_static/static/js/common.js getUiLang, t, dictionary, stock delay string via t
video.js / search.js / about.js / announce.js / category.js Replace hardcoded UI Chinese with t()
earth.js Bilingual city names + Fuzhou tooltip
public/themes/website/1/en/demo/components/*.html Header/footer/mask/empty EN chrome
public/themes/website/1/en/demo/*.html Page EN chrome + lang="en" + inline script strings

Task 1: Add getUiLang + t + base dictionary in common.js

Files:

  • Modify: public/themes/dist_static/static/js/common.js
  • Test: browser console / grep (no unit test harness)

Interfaces:

  • Produces:

    • getUiLang(): 'en' | 'zh'
    • t(key: string, vars?: Record<string, string|number>): string
    • window.getUiLang, window.t (same functions)
  • Consumes: location.pathname; optional .site-header__lang[data-lang-current]

  • Step 1: Insert helper + dictionary near top of the $(function(){...}) region (after Lenis/AOS init is fine; before stock refresh)

Add (exact initial keys — extend later if grep finds more):

	const UI_I18N = {
		zh: {
			"video.play": "视频播放",
			"filter.by_product": "按产品筛选",
			"about.expand_more": "展开更多",
			"about.collapse": "收起",
			"brand.short": "睿能科技",
			"stock.delay_note": "截止 {time}*报价有十五分钟或以上延迟。",
			"contact.name_required": "请输入姓名",
			"contact.phone_required": "请输入手机号",
			"contact.company_required": "请输入公司名称",
			"contact.email_required": "请输入邮箱",
			"contact.submitting": "提交中...",
			"contact.submit": "提交",
			"contact.success": "提交成功,我们会尽快与您联系!",
			"contact.fail": "提交失败,请稍后重试",
			"contact.network_error": "网络错误,请稍后重试",
			"earth.hq_fuzhou": "全球总部福州",
			"earth.hq_fuzhou_html": "全球总部<br>福州"
		},
		en: {
			"video.play": "Video",
			"filter.by_product": "Filter by product",
			"about.expand_more": "Show more",
			"about.collapse": "Show less",
			"brand.short": "RAYNEN",
			"stock.delay_note": "As of {time}* Quotes delayed by 15 minutes or more.",
			"contact.name_required": "Please enter your name",
			"contact.phone_required": "Please enter your phone number",
			"contact.company_required": "Please enter your company name",
			"contact.email_required": "Please enter your email",
			"contact.submitting": "Submitting...",
			"contact.submit": "Submit",
			"contact.success": "Submitted successfully. We will contact you soon.",
			"contact.fail": "Submission failed. Please try again later.",
			"contact.network_error": "Network error. Please try again later.",
			"earth.hq_fuzhou": "Global HQ Fuzhou",
			"earth.hq_fuzhou_html": "Global HQ<br>Fuzhou"
		}
	};

	function getUiLang() {
		const fromHeader = document.querySelector(".site-header__lang")?.getAttribute("data-lang-current");
		if (fromHeader === "en" || fromHeader === "zh") return fromHeader;
		const seg = location.pathname.replace(/^\//, "").split("/")[0] || "";
		return seg === "en" ? "en" : "zh";
	}

	function t(key, vars) {
		const lang = getUiLang();
		const table = UI_I18N[lang] || UI_I18N.zh;
		let str = table[key] ?? UI_I18N.zh[key] ?? key;
		if (vars && typeof vars === "object") {
			Object.keys(vars).forEach((k) => {
				str = str.replace(new RegExp(`\\{${k}\\}`, "g"), String(vars[k]));
			});
		}
		return str;
	}

	window.getUiLang = getUiLang;
	window.t = t;
  • Step 2: Replace stock delay assignment to use t

Find in initStockQuoteRefresh / applyQuote:

timeEl.textContent = `截止 ${data.updateTime}*报价有十五分钟或以上延迟。`;

Replace with:

timeEl.textContent = t("stock.delay_note", { time: data.updateTime });
  • Step 3: Verify helper in browser

Open /en/ any page with DevTools:

getUiLang()  // "en"
t("video.play")  // "Video"
t("stock.delay_note", { time: "2026-09-07 10:00:00" })

Open a zh page: getUiLang()"zh", t("video.play")"视频播放".

  • Step 4: Commit
git add public/themes/dist_static/static/js/common.js
git commit -m "feat(i18n): add getUiLang/t dictionary for shared UI strings"

Task 2: Wire shared page JS to t()

Files:

  • Modify: public/themes/dist_static/static/js/video.js
  • Modify: public/themes/dist_static/static/js/search.js
  • Modify: public/themes/dist_static/static/js/about.js
  • Modify: public/themes/dist_static/static/js/announce.js
  • Modify: public/themes/dist_static/static/js/category.js

Interfaces:

  • Consumes: window.t / t (common.js loaded first via import "./common.js")

  • Step 1: Update video.js

Replace "视频播放" defaults with t("video.play").
Replace $btn.find("span").text("按产品筛选") with t("filter.by_product").

  • Step 2: Update search.js

Replace "视频播放" fallbacks with t("video.play").
Keep the /^播放[::]/ strip for aria-label parsing (works for Chinese CMS labels); if EN aria uses Play:, also allow:

card.getAttribute("aria-label")?.replace(/^(播放|Play)\s*[::]\s*/i, "").trim() || t("video.play")
  • Step 3: Update about.js
btn.querySelector("span").textContent = expanded ? t("about.collapse") : t("about.expand_more");
  • Step 4: Update announce.js
$btn.find("span").text(t("filter.by_product"));
  • Step 5: Update category.js
if (name) document.title = `${name} - ${t("brand.short")}`;
  • Step 6: Smoke

  • /en/video.html (or routed EN video): default modal title English when empty.

  • /about zh: toggle still 展开更多/收起.

  • /en/about: Show more / Show less.

  • Step 7: Commit

git add public/themes/dist_static/static/js/video.js public/themes/dist_static/static/js/search.js public/themes/dist_static/static/js/about.js public/themes/dist_static/static/js/announce.js public/themes/dist_static/static/js/category.js
git commit -m "feat(i18n): localize shared page JS UI strings via t()"

Task 3: Localize earth.js city names + HQ tooltip

Files:

  • Modify: public/themes/dist_static/static/js/earth.js

Interfaces:

  • Consumes: getUiLang(), t()

  • Produces: markers whose displayed name matches UI lang

  • Step 1: Change markersData entries to bilingual names

Pattern for each city:

{
  nameZh: "上海",
  nameEn: "Shanghai",
  lat: 31.2304,
  lon: 121.4737
},

Full English map (use exactly):

nameZh nameEn
上海 Shanghai
东京 Tokyo
伊斯坦布尔 Istanbul
伦敦 London
加尔各答 Kolkata
北京 Beijing
华沙 Warsaw
南京 Nanjing
吉隆坡 Kuala Lumpur
圣保罗 São Paulo
圣安东尼奥 San Antonio
墨西哥城 Mexico City
多伦多 Toronto
奥克兰 Auckland
孟买 Mumbai
安地比斯 (keep transliteration from existing intent; if unclear use original pinyin/English already known — Antananarivo only if that was the city; otherwise keep a clear English label matching lat/lon)
山景城 Mountain View
巴黎 Paris
布宜诺斯艾利斯 Buenos Aires
开普敦 Cape Town
悉尼 Sydney
新加坡 Singapore
新德里 New Delhi
曼谷 Bangkok
法兰克福 Frankfurt
波哥大 Bogotá
深圳 Shenzhen
牛津 Oxford
特拉维夫 Tel Aviv
科伦坡 Colombo
米兰 Milan
纽约 New York
莫斯科 Moscow
达卡 Dhaka
迪拜 Dubai
邦加罗尔 Bengaluru
金奈 Chennai
雅加达 Jakarta
首尔 Seoul
香港 Hong Kong
全球总部福州 Global HQ Fuzhou

If “安地比斯” coordinates are unclear, keep nameEn as a reasonable English label and do not invent a wrong city.

  • Step 2: Resolve display name when creating markers

Replace data.name usage:

function markerName(data) {
  return getUiLang() === "en" ? (data.nameEn || data.nameZh) : (data.nameZh || data.nameEn);
}

Update:

  • if (data.name === "全球总部福州")if (data.nameZh === "全球总部福州")
  • marker.userData = { name: markerName(data) };
  • fuzhouTooltip.innerHTML = t("earth.hq_fuzhou_html");

Ensure earth.js runs after common.js on pages that load both (home/about already modulepreload common via page entry). If earth.js is a standalone module without import, add at top of its runtime:

const getUiLang = window.getUiLang || (() => (location.pathname.split("/")[1] === "en" ? "en" : "zh"));
const t = window.t || ((k) => k);
  • Step 3: Smoke

  • /en/ home or about: hover marker → English city name; Fuzhou tooltip English.

  • zh home: Chinese names unchanged.

  • Step 4: Commit

git add public/themes/dist_static/static/js/earth.js
git commit -m "feat(i18n): bilingual earth marker city names"

Files:

  • Modify: public/themes/website/1/en/demo/components/header.html

  • Modify: public/themes/website/1/en/demo/components/footer.html

  • Modify: public/themes/website/1/en/demo/components/mask.html

  • Modify: public/themes/website/1/en/demo/components/empty.html

  • Step 1: Translate user-visible hardcoded strings

Examples (apply consistently; leave PHP comments Chinese):

  • aria-label="社交账号"Social accounts
  • aria-label="微信"WeChat (popup caption 官方微信Official WeChat)
  • aria-label="抖音"Douyin (or TikTok if product prefers — use Douyin)
  • 微博Weibo; 知乎Zhihu
  • 切换语言Switch language
  • 主导航 / 移动导航Main navigation / Mobile navigation
  • 搜索Search; 关闭导航菜单Close menu
  • 展开/收起Expand/collapse
  • Logo aria-label / alt: RAYNEN or RAYNEN Technology (drop Chinese in EN alt)
  • Footer: 股票代码Stock code; 关注我们:Follow us:; 官方微信Official WeChat; 官方视频号Official Channels; 版权所有All rights reserved; 网站地图Sitemap; 隐私声明Privacy Policy
  • Footer unit Yuan
  • Promo hardcoded 了解睿能最新展会信息Learn about RAYNEN’s latest events (only if hardcoded, not from CMS)
  • Hardcoded 解决方案 label if not from $vo.titleSolutions

Do not change {hcTaglib:nav} titles.

  • Step 2: Grep components for leftover visible Chinese
rg -n "[\p{Han}]" public/themes/website/1/en/demo/components --glob "*.html"

Ignore: comments, SVG ids, PHP comments, CMS echoes.

  • Step 3: Commit
git add public/themes/website/1/en/demo/components
git commit -m "feat(i18n): English copy for EN demo header/footer/mask/empty"

Task 5: Translate EN page templates + set lang="en"

Files:

  • Modify all under public/themes/website/1/en/demo/*.html that still have lang="zh-CN" or hardcoded Chinese UI

Pages: single_index, contact, product, about, investment, solution, solution2, news, news-detail, search, single_search, download, faq, video, announce, category

  • Step 1: Batch fix html lang

Replace on every EN demo page:

<html lang="zh-CN">

<html lang="en">
  • Step 2: Translate page chrome (common patterns)

Apply across pages where hardcoded:

zh en
探索更多 Explore more
立即下载 Download
请输入您想了解的内容 Search what you want to know
请输入您想下载的文件 Search files to download
请输入您想搜索问题的关键词 Search FAQ keywords
请输入您想搜索视频的关键词 Search video keywords
暂无相关资料 / 问题 / 视频 No matching resources / FAQs / videos
视频播放 Video
了解产品 Learn more
资料下载 Downloads
股票信息 / 股票代码 Stock information / Stock code
最高(元)等 metrics High (Yuan), Low (Yuan), Volume (10k lots), Turnover (CNY 10k) — keep units clear
客服热线 Hotline
下载中心 / 常见问题 / 视频教程 / 产品公告 Download Center / FAQ / Video Tutorials / Product Notices
Contact form labels/placeholders/options/submit Natural EN (Name, Phone, Company, Email, Industry, Business type, …)

contact.html select options: translate both visible text and value to English in the EN template only (EN form posts English values).

  • Step 3: Translate contact.html inline script strings via window.t
if (!name) { alert(t("contact.name_required")); return; }
if (!phone) { alert(t("contact.phone_required")); return; }
if (!company) { alert(t("contact.company_required")); return; }
if (!email) { alert(t("contact.email_required")); return; }
// ...
$submitBtn.prop("disabled", true).text(t("contact.submitting"));
// success:
showFormToast(t("contact.success"));
// fail:
alert(res.msg || t("contact.fail"));
// network:
alert(t("contact.network_error"));
// complete:
$submitBtn.prop("disabled", false).text(t("contact.submit"));

Leave Chinese comments in that script untouched.

  • Step 4: Grep EN demo pages
rg -n "[\p{Han}]" public/themes/website/1/en/demo --glob "*.html"

Triage each hit: comment / SVG id / CMS / must-fix UI.

  • Step 5: Smoke checklist

  • /en/contact.html: form UI English; validation English.

  • /en/download.html: placeholders + Download.

  • /en/ home: Explore more buttons English.

  • /en/investment.html: stock section labels English; delay note English after refresh.

  • zh contact still Chinese.

  • Step 6: Commit

git add public/themes/website/1/en/demo
git commit -m "feat(i18n): English UI copy for EN demo pages"

Task 6: Final acceptance sweep

Files: none new (verification only)

  • Step 1: Shared JS user-string grep
rg -n "[\p{Han}]" public/themes/dist_static/static/js --glob "*.js"

Allowed leftovers: comments only; earth nameZh fields; dictionary zh entries in common.js.

  • Step 2: Confirm zh site not broken

Spot-check zh home, about expand, video modal, footer stock note → Chinese.

  • Step 3: Confirm EN site

Spot-check EN home, contact, investment, about earth tooltips → English chrome.

  • Step 4: Commit only if tiny fixes were needed; otherwise done
git status
# if fixups:
git add -u
git commit -m "fix(i18n): leftover EN demo UI strings"

Spec coverage check

Spec requirement Task
EN demo hardcoded UI → English 4, 5
Shared JS bilingual via dictionary 1, 2
earth city names 3
Comments not translated Global + all tasks
CMS fields untouched Global
html lang=en 5
getUiLang / URL en prefix 1
Stock delay note i18n 1
Contact inline alerts 5
Acceptance grep/smoke 6

Placeholder scan

No TBD/TODO steps; commands and key tables are concrete.