talizen 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cms.js +26 -2
- package/i18n.d.ts +24 -8
- package/i18n.js +35 -1
- package/package.json +1 -1
package/cms.js
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
import { requestJson } from "./core.js";
|
|
2
|
+
import { getLocale } from "./i18n.js";
|
|
3
|
+
// 字段级本地化解码:把 body._i18n[当前语言] 覆盖到同级字段并删除 _i18n。
|
|
4
|
+
// 无论 SSR(getServerSideProps 取数)、客户端还是编辑器预览,都在此处按当前语言解码——
|
|
5
|
+
// 渲染引擎不再解码 CMS,只透传原始 body(含 _i18n)。用 getLocale()(非 hook),
|
|
6
|
+
// 因此在 getServerSideProps 里调用也合法。当前语言由引擎注入的 __TALIZEN_I18N__ 提供。
|
|
7
|
+
function decodeBodyLocalization(body) {
|
|
8
|
+
if (!body || typeof body !== "object" || !("_i18n" in body))
|
|
9
|
+
return body;
|
|
10
|
+
const { _i18n, ...base } = body;
|
|
11
|
+
const locale = getLocale().locale;
|
|
12
|
+
const over = locale && _i18n ? _i18n[locale] : undefined;
|
|
13
|
+
return over && typeof over === "object" ? { ...base, ...over } : base;
|
|
14
|
+
}
|
|
15
|
+
function decodeItem(item) {
|
|
16
|
+
return item && item.body ? { ...item, body: decodeBodyLocalization(item.body) } : item;
|
|
17
|
+
}
|
|
2
18
|
export async function getContentCollection(key, options) {
|
|
3
19
|
return requestJson(`/cms/${key}`, undefined, options);
|
|
4
20
|
}
|
|
@@ -14,6 +30,8 @@ export async function listContents(key, params = {}, options) {
|
|
|
14
30
|
filter: params.filter,
|
|
15
31
|
}),
|
|
16
32
|
}, options);
|
|
33
|
+
if (response.list)
|
|
34
|
+
response.list = response.list.map(decodeItem);
|
|
17
35
|
return response;
|
|
18
36
|
}
|
|
19
37
|
export async function getContent(key, slug, params, options) {
|
|
@@ -22,10 +40,11 @@ export async function getContent(key, slug, params, options) {
|
|
|
22
40
|
if (params?.builtinRef != null) {
|
|
23
41
|
url.searchParams.set("builtin_ref", String(params.builtinRef));
|
|
24
42
|
}
|
|
25
|
-
|
|
43
|
+
const item = await requestJson(url.pathname + url.search, undefined, options);
|
|
44
|
+
return decodeItem(item);
|
|
26
45
|
}
|
|
27
46
|
export async function getContentWithPrevNext(key, slug, params = {}, options) {
|
|
28
|
-
|
|
47
|
+
const res = await requestJson(`/cms/${key}/content_with_prev_next`, {
|
|
29
48
|
method: "POST",
|
|
30
49
|
body: JSON.stringify({
|
|
31
50
|
slug,
|
|
@@ -37,4 +56,9 @@ export async function getContentWithPrevNext(key, slug, params = {}, options) {
|
|
|
37
56
|
filter: params.filter,
|
|
38
57
|
}),
|
|
39
58
|
}, options);
|
|
59
|
+
return {
|
|
60
|
+
current: res.current ? decodeItem(res.current) : res.current,
|
|
61
|
+
next: res.next ? decodeItem(res.next) : res.next,
|
|
62
|
+
prev: res.prev ? decodeItem(res.prev) : res.prev,
|
|
63
|
+
};
|
|
40
64
|
}
|
package/i18n.d.ts
CHANGED
|
@@ -23,6 +23,20 @@ declare global {
|
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
25
|
export declare function useLocale(): LocaleRuntime;
|
|
26
|
+
/**
|
|
27
|
+
* 读取当前语言运行时信息——与 useLocale() 完全等价,但命名为 get*(**不是 hook**),
|
|
28
|
+
* 用于 getServerSideProps / generateMetadata 等**服务端取数场景**(对齐 next-intl 的 getLocale)。
|
|
29
|
+
* 组件渲染里用 useLocale()。SSR 与客户端返回一致。
|
|
30
|
+
*
|
|
31
|
+
* ```ts
|
|
32
|
+
* export async function getServerSideProps(ctx) {
|
|
33
|
+
* const { locale } = getLocale() // ✅ 服务端取数用 get*
|
|
34
|
+
* const posts = await listContents("blog") // 内部按当前 locale 自动解码 CMS
|
|
35
|
+
* return { props: { posts } }
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare function getLocale(): LocaleRuntime;
|
|
26
40
|
/**
|
|
27
41
|
* 给站内路径加语言前缀(默认语言不加前缀)。不传 `locale` 时使用当前语言。
|
|
28
42
|
* 站外链接(协议 / 协议相对 URL)与页内锚点(`#...`)原样返回。
|
|
@@ -63,15 +77,17 @@ declare global {
|
|
|
63
77
|
}
|
|
64
78
|
/** 翻译函数:按 key 取文案(支持点路径),`{var}` 插值;缺失时返回 key 本身。 */
|
|
65
79
|
export type Translator = (key: string, vars?: Record<string, unknown>) => string;
|
|
80
|
+
export declare function useTranslations(namespace?: string): Translator;
|
|
66
81
|
/**
|
|
67
|
-
* 读取 UI
|
|
82
|
+
* 读取 UI 文案翻译器——与 useTranslations() 等价,但命名为 get*(**不是 hook**),
|
|
83
|
+
* 用于 getServerSideProps / generateMetadata 等**服务端取数场景**(对齐 next-intl 的 getTranslations)。
|
|
84
|
+
* 组件渲染里用 useTranslations()。
|
|
68
85
|
*
|
|
69
|
-
* ```
|
|
70
|
-
*
|
|
71
|
-
* t("
|
|
72
|
-
* t("
|
|
86
|
+
* ```ts
|
|
87
|
+
* export async function generateMetadata() {
|
|
88
|
+
* const t = getTranslations("seo")
|
|
89
|
+
* return { title: t("home_title") }
|
|
90
|
+
* }
|
|
73
91
|
* ```
|
|
74
|
-
*
|
|
75
|
-
* UI chrome 用 useTranslations;文章等内容用 CMS 字段级 _i18n(见 listContents/getContent)。
|
|
76
92
|
*/
|
|
77
|
-
export declare function
|
|
93
|
+
export declare function getTranslations(namespace?: string): Translator;
|
package/i18n.js
CHANGED
|
@@ -19,6 +19,22 @@ function readLocaleRuntime() {
|
|
|
19
19
|
export function useLocale() {
|
|
20
20
|
return readLocaleRuntime();
|
|
21
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* 读取当前语言运行时信息——与 useLocale() 完全等价,但命名为 get*(**不是 hook**),
|
|
24
|
+
* 用于 getServerSideProps / generateMetadata 等**服务端取数场景**(对齐 next-intl 的 getLocale)。
|
|
25
|
+
* 组件渲染里用 useLocale()。SSR 与客户端返回一致。
|
|
26
|
+
*
|
|
27
|
+
* ```ts
|
|
28
|
+
* export async function getServerSideProps(ctx) {
|
|
29
|
+
* const { locale } = getLocale() // ✅ 服务端取数用 get*
|
|
30
|
+
* const posts = await listContents("blog") // 内部按当前 locale 自动解码 CMS
|
|
31
|
+
* return { props: { posts } }
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export function getLocale() {
|
|
36
|
+
return readLocaleRuntime();
|
|
37
|
+
}
|
|
22
38
|
/**
|
|
23
39
|
* 给站内路径加语言前缀(默认语言不加前缀)。不传 `locale` 时使用当前语言。
|
|
24
40
|
* 站外链接(协议 / 协议相对 URL)与页内锚点(`#...`)原样返回。
|
|
@@ -83,7 +99,7 @@ function lookupMessage(obj, path) {
|
|
|
83
99
|
*
|
|
84
100
|
* UI chrome 用 useTranslations;文章等内容用 CMS 字段级 _i18n(见 listContents/getContent)。
|
|
85
101
|
*/
|
|
86
|
-
|
|
102
|
+
function buildTranslator(namespace) {
|
|
87
103
|
const messages = readMessages();
|
|
88
104
|
const scoped = namespace ? lookupMessage(messages, namespace) : messages;
|
|
89
105
|
const base = (scoped && typeof scoped === "object" ? scoped : {});
|
|
@@ -95,3 +111,21 @@ export function useTranslations(namespace) {
|
|
|
95
111
|
return text.replace(/\{(\w+)\}/g, (_, k) => (k in vars ? String(vars[k]) : `{${k}}`));
|
|
96
112
|
};
|
|
97
113
|
}
|
|
114
|
+
export function useTranslations(namespace) {
|
|
115
|
+
return buildTranslator(namespace);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* 读取 UI 文案翻译器——与 useTranslations() 等价,但命名为 get*(**不是 hook**),
|
|
119
|
+
* 用于 getServerSideProps / generateMetadata 等**服务端取数场景**(对齐 next-intl 的 getTranslations)。
|
|
120
|
+
* 组件渲染里用 useTranslations()。
|
|
121
|
+
*
|
|
122
|
+
* ```ts
|
|
123
|
+
* export async function generateMetadata() {
|
|
124
|
+
* const t = getTranslations("seo")
|
|
125
|
+
* return { title: t("home_title") }
|
|
126
|
+
* }
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
export function getTranslations(namespace) {
|
|
130
|
+
return buildTranslator(namespace);
|
|
131
|
+
}
|