diff --git a/astro.config.mjs b/astro.config.mjs index db97662..55d87d7 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,16 +1,27 @@ // @ts-check import { defineConfig } from 'astro/config'; +import { fileURLToPath } from 'node:url'; import tailwindcss from '@tailwindcss/vite'; import alpinejs from '@astrojs/alpinejs'; +import node from '@astrojs/node'; + + // https://astro.build/config export default defineConfig({ vite: { - plugins: [tailwindcss()] + plugins: [tailwindcss()], + resolve: { + alias: { + // 路径别名:@ -> 项目 src 目录(与 tsconfig paths 一致) + '@': fileURLToPath(new URL('./src', import.meta.url)), + }, + }, }, + i18n: { defaultLocale: 'en', locales: ['en', 'cn'], @@ -18,9 +29,15 @@ export default defineConfig({ prefixDefaultLocale: true, // 英文在根路径 /shows,中文在 /cn/shows }, }, + build: { // 示例:在构建过程中生 成`page.html` 而不是 `page/index.html`。 // format: 'file' }, - integrations: [alpinejs()] + + integrations: [alpinejs()], + + adapter: node({ + mode: 'standalone' + }) }); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e13d132..1aa04fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.1", "dependencies": { "@astrojs/alpinejs": "^1.0.0", + "@astrojs/node": "^11.1.2", "@tailwindcss/vite": "^4.3.3", "@types/alpinejs": "^3.13.11", "alpinejs": "^3.16.1", @@ -235,6 +236,20 @@ "satteri": "^0.9.1" } }, + "node_modules/@astrojs/node": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@astrojs/node/-/node-11.1.2.tgz", + "integrity": "sha512-lbOjylG18s8wURjT9teqa/SPXVtVpBgm9vccEg/BXlrW3ktqqgFv23vtOswEfluDmx2Z74ngyGE6hrGC14qWow==", + "license": "MIT", + "dependencies": { + "@astrojs/internal-helpers": "0.10.2", + "send": "^1.2.1", + "server-destroy": "^1.0.1" + }, + "peerDependencies": { + "astro": "^7.0.0" + } + }, "node_modules/@astrojs/prism": { "version": "4.0.2", "resolved": "https://registry.npmmirror.com/@astrojs/prism/-/prism-4.0.2.tgz", @@ -522,6 +537,16 @@ "tslib": "^2.4.0" } }, + "node_modules/@emnapi/runtime": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz", + "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@emnapi/wasi-threads": { "version": "2.0.1", "resolved": "https://registry.npmmirror.com/@emnapi/wasi-threads/-/wasi-threads-2.0.1.tgz", @@ -2447,8 +2472,7 @@ "version": "3.13.11", "resolved": "https://registry.npmjs.org/@types/alpinejs/-/alpinejs-3.13.11.tgz", "integrity": "sha512-3KhGkDixCPiLdL3Z/ok1GxHwLxEWqQOKJccgaQL01wc0EVM2tCTaqlC3NIedmxAXkVzt/V6VTM8qPgnOHKJ1MA==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@types/estree": { "version": "1.0.9", @@ -2524,7 +2548,6 @@ "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.16.1.tgz", "integrity": "sha512-QXcW8MK9JoG8GZ7vCt2cXJlcEPIA7Xk/7IQ1+L2iLp7sXcIxct0PrgidmHzK97gD9QlfUjHXPxujdZ1mC2PYVg==", "license": "MIT", - "peer": true, "dependencies": { "@vue/reactivity": "~3.1.1" } @@ -2889,12 +2912,38 @@ "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", "license": "CC0-1.0" }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/defu": { "version": "6.1.7", "resolved": "https://registry.npmmirror.com/defu/-/defu-6.1.7.tgz", "integrity": "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==", "license": "MIT" }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmmirror.com/dequal/-/dequal-2.0.3.tgz", @@ -3023,6 +3072,21 @@ "node": ">=4" } }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/enhanced-resolve": { "version": "5.24.5", "resolved": "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz", @@ -3060,7 +3124,6 @@ "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", "hasInstallScript": true, "license": "MIT", - "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -3096,12 +3159,27 @@ "@esbuild/win32-x64": "0.28.1" } }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "license": "MIT" }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/eventemitter3": { "version": "5.0.4", "resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-5.0.4.tgz", @@ -3185,6 +3263,15 @@ "node": ">=20" } }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", @@ -3369,6 +3456,32 @@ "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", "license": "BSD-2-Clause" }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, "node_modules/iron-webcrypto": { "version": "1.2.1", "resolved": "https://registry.npmmirror.com/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz", @@ -3836,6 +3949,31 @@ ], "license": "MIT" }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/mrmime": { "version": "2.0.1", "resolved": "https://registry.npmmirror.com/mrmime/-/mrmime-2.0.1.tgz", @@ -3845,6 +3983,12 @@ "node": ">=10" } }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/nanoid": { "version": "3.3.16", "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.16.tgz", @@ -3948,6 +4092,18 @@ "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", "license": "MIT" }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/oniguruma-parser": { "version": "0.12.2", "resolved": "https://registry.npmmirror.com/oniguruma-parser/-/oniguruma-parser-0.12.2.tgz", @@ -4112,6 +4268,19 @@ "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==", "license": "MIT" }, + "node_modules/range-parser": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz", + "integrity": "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/readdirp": { "version": "5.0.0", "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-5.0.0.tgz", @@ -4250,6 +4419,44 @@ "node": ">=10" } }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/server-destroy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", + "integrity": "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==", + "license": "ISC" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, "node_modules/sharp": { "version": "0.35.3", "resolved": "https://registry.npmmirror.com/sharp/-/sharp-0.35.3.tgz", @@ -4356,6 +4563,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/stringify-entities": { "version": "4.0.4", "resolved": "https://registry.npmmirror.com/stringify-entities/-/stringify-entities-4.0.4.tgz", @@ -4473,6 +4689,15 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, "node_modules/trim-lines": { "version": "3.0.1", "resolved": "https://registry.npmmirror.com/trim-lines/-/trim-lines-3.0.1.tgz", @@ -4759,7 +4984,6 @@ "resolved": "https://registry.npmmirror.com/vite/-/vite-8.2.0.tgz", "integrity": "sha512-pn+CFpM0lwDeKwmOq1ZaBK/9sjorZcgqxki6MbY/jPEVd9vichIlmlD4HmQ5wdP5EgqQCFRaACBxMC7uEGc6lQ==", "license": "MIT", - "peer": true, "dependencies": { "lightningcss": "^1.33.0", "picomatch": "^4.0.5", diff --git a/package.json b/package.json index 4b8d0a8..a01045d 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ }, "dependencies": { "@astrojs/alpinejs": "^1.0.0", + "@astrojs/node": "^11.1.2", "@tailwindcss/vite": "^4.3.3", "@types/alpinejs": "^3.13.11", "alpinejs": "^3.16.1", diff --git a/src/components/Breadcrumb.astro b/src/components/Breadcrumb.astro new file mode 100644 index 0000000..f8ccd6e --- /dev/null +++ b/src/components/Breadcrumb.astro @@ -0,0 +1,51 @@ +--- +import { useTranslations, DEFAULT_LOCALE, type Locale } from "@/i18n/utils"; + +interface Crumb { + /** i18n key:英文原文,如 'Home' / 'Runway Archive';中文环境自动取字典翻译 */ + label: string; + href: string; +} + +interface Props { + /** 中间层级的面包屑项(不含末项)。末项由 提供(如动态年份) */ + items?: Crumb[]; + /** 可选:显式指定语言;缺省时跟随当前页面语言(Astro.currentLocale) */ + locale?: string; +} + +const { items = [], locale } = Astro.props; +const currentLocale = (locale ?? Astro.currentLocale ?? DEFAULT_LOCALE) as Locale; +const { t } = useTranslations(currentLocale); +--- + + + + diff --git a/src/components/Index.astro b/src/components/Index.astro index 64213bd..3b9e7eb 100644 --- a/src/components/Index.astro +++ b/src/components/Index.astro @@ -1,15 +1,14 @@ --- -import ComingSoon from "./ComingSoon.astro" -import { getShows, seriesLabel } from "../lib/data" -import { useTranslations, DEFAULT_LOCALE, type Locale } from "../i18n/utils" +import ComingSoon from "@/components/ComingSoon.astro" +import { getShows, seriesLabel } from "@/lib/data" +import { getI18n } from "@/i18n/utils" // SSR 预取走秀数据 const shows = await getShows(20) -// 国际化:取当前页面语言(Astro 路由解析)与翻译函数 -const locale = (Astro.currentLocale as Locale) ?? DEFAULT_LOCALE -const { t } = useTranslations(locale) +// 国际化:一行取当前语言 + 翻译函数 +const { locale, t } = getI18n(Astro) type GalleryItem = { src: string; diff --git a/src/components/RunwayLooks.astro b/src/components/RunwayLooks.astro new file mode 100644 index 0000000..e69de29 diff --git a/src/components/Welcome.astro b/src/components/Welcome.astro index 1b2cf9c..451bd2d 100644 --- a/src/components/Welcome.astro +++ b/src/components/Welcome.astro @@ -1,6 +1,6 @@ --- -import astroLogo from '../assets/astro.svg'; -import background from '../assets/background.svg'; +import astroLogo from '@/assets/astro.svg'; +import background from '@/assets/background.svg'; ---
diff --git a/src/components/pages/About.astro b/src/components/pages/About.astro index 3f4ac53..50366c4 100644 --- a/src/components/pages/About.astro +++ b/src/components/pages/About.astro @@ -1,6 +1,6 @@ --- // 页面主体(与语言无关的内容),由根页面与 [locale] 页面共用 -import ComingSoon from "../../components/ComingSoon.astro" +import ComingSoon from "@/components/ComingSoon.astro" --- diff --git a/src/components/pages/Contact.astro b/src/components/pages/Contact.astro index cf241e7..157bcd6 100644 --- a/src/components/pages/Contact.astro +++ b/src/components/pages/Contact.astro @@ -1,6 +1,6 @@ --- // 页面主体(与语言无关的内容),由根页面与 [locale] 页面共用 -import ComingSoon from "../../components/ComingSoon.astro" +import ComingSoon from "@/components/ComingSoon.astro" --- diff --git a/src/components/pages/LatestProjects.astro b/src/components/pages/LatestProjects.astro index abd52e2..e4bb351 100644 --- a/src/components/pages/LatestProjects.astro +++ b/src/components/pages/LatestProjects.astro @@ -1,6 +1,6 @@ --- // 页面主体(与语言无关的内容),由根页面与 [locale] 页面共用 -import ComingSoon from "../../components/ComingSoon.astro" +import ComingSoon from "@/components/ComingSoon.astro" --- diff --git a/src/components/pages/Login.astro b/src/components/pages/Login.astro index f27463e..b6df1c1 100644 --- a/src/components/pages/Login.astro +++ b/src/components/pages/Login.astro @@ -1,6 +1,6 @@ --- // 页面主体(与语言无关的内容),由根页面与 [locale] 页面共用 -import ComingSoon from "../../components/ComingSoon.astro" +import ComingSoon from "@/components/ComingSoon.astro" --- diff --git a/src/components/pages/Portfolio.astro b/src/components/pages/Portfolio.astro index e96a16a..f03a589 100644 --- a/src/components/pages/Portfolio.astro +++ b/src/components/pages/Portfolio.astro @@ -1,6 +1,6 @@ --- // 页面主体(与语言无关的内容),由根页面与 [locale] 页面共用 -import ComingSoon from "../../components/ComingSoon.astro" +import ComingSoon from "@/components/ComingSoon.astro" --- diff --git a/src/components/pages/Register.astro b/src/components/pages/Register.astro index da59b7c..db1283b 100644 --- a/src/components/pages/Register.astro +++ b/src/components/pages/Register.astro @@ -1,6 +1,6 @@ --- // 页面主体(与语言无关的内容),由根页面与 [locale] 页面共用 -import ComingSoon from "../../components/ComingSoon.astro" +import ComingSoon from "@/components/ComingSoon.astro" --- diff --git a/src/components/pages/article.astro b/src/components/pages/article.astro index df76420..2ed6938 100644 --- a/src/components/pages/article.astro +++ b/src/components/pages/article.astro @@ -31,7 +31,7 @@
-

+

@@ -42,32 +42,8 @@
- -
-
- Report -
-
- -
-
-
-
-
- Gallery -
- -
diff --git a/src/components/pages/articles.astro b/src/components/pages/articles.astro index 37ae6ef..2216719 100644 --- a/src/components/pages/articles.astro +++ b/src/components/pages/articles.astro @@ -1,5 +1,5 @@ --- -import { getReports, fmtDate } from "../../lib/data" +import { getReports, fmtDate } from "@/lib/data" // 文章展示创意布局页:复用你现有的 Layout 外壳。 // 数据由数据层 getReports() 统一从后端公开接口拉取(见 src/lib/data.ts); diff --git a/src/i18n/dictionary.ts b/src/i18n/dictionary.ts index 4175b15..e0b9f5d 100644 --- a/src/i18n/dictionary.ts +++ b/src/i18n/dictionary.ts @@ -1,4 +1,4 @@ -import { DEFAULT_LOCALE, type Locale } from './config'; +import { DEFAULT_LOCALE, type Locale } from '@/i18n/config'; /** * 单文件翻译字典。 @@ -18,18 +18,25 @@ type OtherLocale = Exclude; type TranslationEntry = Partial>; export const dict: Record = { - Portfolio: { cn: '作品集' }, - 'All Shows': { cn: '全部走秀' }, + // ── 导航 / Navigation ── + 'About': { cn: '关于' }, + 'All Shows': { cn: '全部走秀' }, + 'Contact': { cn: '联系' }, + 'Contact Us': { cn: '联系我们' }, + 'Home': { cn: '首页' }, 'Latest Projects': { cn: '最新项目' }, - About: { cn: '关于' }, - 'Contact Us': { cn: '联系我们' }, - Login: { cn: '登录' }, - Signup: { cn: '注册' }, - Contact: { cn: '联系' }, - 'Back to top': { cn: '回到顶部' }, + 'Login': { cn: '登录' }, + 'Portfolio': { cn: '作品集' }, + 'Runway Archive': { cn: '走秀档案' }, + 'Signup': { cn: '注册' }, + + // ── 控件 / Controls ── + 'Back to top': { cn: '回到顶部' }, + 'Next': { cn: '下一组' }, + 'Previous': { cn: '上一组' }, + + // ── 页脚 / Footer ── '© 2026 PORTFOLIO STUDIO. ALL RIGHTS RESERVED.': { cn: '© 2026 PORTFOLIO STUDIO. 保留所有权利。' }, - Previous: { cn: '上一组' }, - Next: { cn: '下一组' }, }; /** 把 {name} 形式的占位符替换成参数值。 */ diff --git a/src/i18n/utils.ts b/src/i18n/utils.ts index 09c1e52..1b56aef 100644 --- a/src/i18n/utils.ts +++ b/src/i18n/utils.ts @@ -1,6 +1,6 @@ import { getLocaleByPath } from 'astro:i18n'; -import { DEFAULT_LOCALE, LOCALES, type Locale } from './config'; -import { translate } from './dictionary'; +import { DEFAULT_LOCALE, LOCALES, type Locale } from '@/i18n/config'; +import { translate } from '@/i18n/dictionary'; /** * 从 URL 解析语言,委托 Astro 内置的 astro:i18n.getLocaleByPath。 @@ -29,5 +29,17 @@ export function useTranslations(locale: Locale) { return { t, locale }; } +/** + * 一行取「当前语言 + 翻译函数」,干掉每个页面重复的样板: + * const { locale, t } = getI18n(Astro) + * 内部用 Astro.currentLocale(与 Layout 判断语言的方式一致), + * 取不到时回退默认语言。参数只要求含 currentLocale 字段,避免耦合 Astro 全局类型。 + */ +export function getI18n(Astro: { currentLocale?: string | undefined }) { + const locale = (Astro.currentLocale as Locale) ?? DEFAULT_LOCALE; + const { t } = useTranslations(locale); + return { locale, t }; +} + export { LOCALES, DEFAULT_LOCALE }; export type { Locale }; diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index 19da87b..f37ad6c 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -1,9 +1,9 @@ --- -import '../styles/global.css' +import '@/styles/global.css' import { getRelativeLocaleUrl } from 'astro:i18n' -import { useTranslations, DEFAULT_LOCALE, type Locale } from '../i18n/utils' -import { LOCALES, LOCALE_NAMES, isLocaleSegment } from '../i18n/config' -import LanguageDetector from '../components/LanguageDetector.astro' +import { getI18n } from '@/i18n/utils' +import { LOCALES, LOCALE_NAMES, isLocaleSegment } from '@/i18n/config' +import LanguageDetector from '@/components/LanguageDetector.astro' const { title = 'Portfolio Studio', @@ -12,14 +12,21 @@ const { activeThemePalette = null, } = Astro.props; -const locale = (Astro.currentLocale as Locale) ?? DEFAULT_LOCALE -const { t } = useTranslations(locale) +const { locale, t } = getI18n(Astro) + +// 当前路径(去掉语言前缀),供语言切换器「换前缀、留路径」用,例如 /cn/women → /women +const pathSegments = Astro.url.pathname.split('/'); +const firstSegment = pathSegments[1] || ''; +const currentPath = (LOCALES as readonly string[]).includes(firstSegment) + ? '/' + pathSegments.slice(2).filter(Boolean).join('/') || '/' + : Astro.url.pathname; +const queryString = Astro.url.search; --- - + @@ -80,9 +87,9 @@ const { t } = useTranslations(locale) > {LOCALES.map((l) => (
  • -