SAP Spartacus Translation(翻译) 的实现架构概述
在典型的 Spartacus 店面中,大部分内容要么来自 CMS,要么来自产品内容。 但是,对于店面站点标签(例如按钮中的文本),内容存储在单独的文件中,并且可以对这些文件进行本地化(即翻译)。
Spartacus 使用 i18next 库作为其翻译机制,并使用 i18next-xhr-backend 延迟加载翻译块。 这两个库都有丰富的 API,但 Spartacus 只支持其中的一部分,并将它们视为实现细节。 因此,Spartacus 不支持在您的应用程序中自定义使用 i18next。
为了快速开始,从@spartacus/assets 导入预定义的 Spartacus 翻译(目前只有英文),并在 B2cStorefrontModule 的配置中注册它们。 下面是一个例子:
import { translations, translationChunksConfig } from '@spartacus/assets';
// ...
imports: [
B2cStorefrontModule.withConfig({
i18n: {
resources: translations,
chunks: translationChunksConfig
}
})
];
Adding Translations for Other Languages
除了使用预定义的 Spartacus 翻译,您还可以提供自己的英语翻译,并添加其他语言的翻译。 下面是一个例子:
import { translations, translationChunksConfig } from '@spartacus/assets';
// ...
imports: [
B2cStorefrontModule.withConfig({
i18n: {
resources: {
en: translations, // or YOUR_ENGLISH_TRANSLATIONS,
de: YOUR_GERMAN_TRANSLATIONS,
...
},
chunks: translationChunksConfig
}
})
];
这会将翻译编译到您的应用程序 JS 包中。 尽管这对于快速启动来说很好,但在生产中,您可能希望对翻译块利用延迟加载。
Overwriting Individual Translations
要覆盖单个翻译,需要在默认翻译之后提供具有覆盖的对象。 下面是一个例子:
// app.module
import { translations } from '@spartacus/assets';
// ...
export const translationOverwrites = {
en: { // lang
cart: { // chunk
cartDetails: { // keys (nested)
proceedToCheckout: 'Proceed to Checkout',
},
},
},
};
// ...
imports: [
B2cStorefrontModule.withConfig({
i18n: { resources: translations }
}),
ConfigModule.withConfig({
i18n: { resources: translationOverwrites }
})
]
Fallback Language
如果缺少特定键的翻译,生产模式下的店面将显示不间断的空格字符。 为了更容易捕获丢失的键,在开发模式下,Spartacus 显示翻译键前面带有块的名称和冒号(例如,[common:form.confirm])。
为了在缺少翻译时提供更好的用户体验,您可以指定后备语言。 设置 fallbackLang 选项可确保对于每个丢失的翻译,使用后备语言的等效项。
以下是使用英语作为后备语言的示例配置:
import { translations, translationChunksConfig } from '@spartacus/assets';
// ...
imports: [
B2cStorefrontModule.withConfig({
i18n: {
resources: translations,
chunks: translationChunksConfig,
fallbackLang: 'en',
}
})
];
Lazy Loading
翻译按语言和命名块进行结构化,因此您只能加载当前语言和当前页面的翻译资源。 以下是翻译资源的结构示例:
interface TranslationResources {
[lang: string]: {
[chunkName: string]: {
[key: string]: any; // value or nested object with keys
};
};
}
要利用延迟加载,您需要为每种特定语言和块提供不同的 JSON 文件,并使用 {{lng}} 语言占位符和 {{ns}} 占位符为块配置 JSON 文件的 URL。 下面是一个例子:
imports: [
B2cStorefrontModule.withConfig({
i18n: {
backend: {
loadPath: 'assets/i18n-assets/{{lng}}/{{ns}}.json'
},
chunks: translationChunksConfig
}
})
];
对于 Spartacus,您可以在 @spartacus/storefront 的 /i18n-assets 文件夹中找到带有翻译的预定义 JSON 文件。 您需要从您自己的自定义端点或通过将它们复制到 Angular 应用程序的 /assets 文件夹中来提供这些文件。
cp ./node_modules/@spartacus/assets/i18n-assets ./src/assets -r
Handling Translations in HTML
要处理 HTML 中的翻译,您可以使用 cxTranslate 管道。 下面是一个例子:
<input placeholder="{{ 'searchBox.searchHere' | cxTranslate }}" />
Configuring Chunks and Namespace Mapping
每个 key 都属于一个命名空间,每个命名空间都封装在一个chunk中(比如下面例子中的i18n.chunks)。 需要配置来解析哪个键属于哪个命名空间和块。 下面是一个例子:
imports: [
B2cStorefrontModule.withConfig({
i18n: {
backend: {
loadPath: 'assets/i18n-assets/{{lng}}/{{ns}}.json'
},
chunks: {
...
common: ['searchBox', 'sorting', ...],
cart: ['cartDetails', 'cartItems', ...]
product: ['productDetails', 'productList', ...]
...
}
}
})
];
对应的 common.ts 的例子:
cxTranslate 也支持传入参数:
Using Translations in TypeScript Code
也可以使用 TypeScript 代码进行翻译,即利用 Spartacus 的 TranslationService 服务。
import { TranslationService } from '@spartacus/core';
constructor(
private translation: TranslationService
) {}
getPaymentCardContent(payment: PaymentDetails): Observable<Card> {
 return combineLatest([
this.translation.translate('paymentForm.payment'),
this.translation.translate('paymentCard.expires', {
month: payment.expiryMonth,
year: payment.expiryYear,
}),
]).pipe(
map(([textTitle, textExpires]) => {
return {
title: textTitle,
textBold: payment.accountHolderName,
text: [payment.cardType.name, payment.cardNumber, textExpires],
};
})
);
}
HTML 里的用法:
<cx-card
[content]="getPaymentCardContent(order.paymentInfo) | async"
></cx-card>
- 点赞
- 收藏
- 关注作者
评论(0)