# 国际化

> 让 Shoplazza 主题可翻译、可感知语言区域：用 t 过滤器的翻译 key、插值动态值，并适配格式与从右到左的布局。

为了面向全球顾客，构建主题时应让文本、布局和格式随顾客的语言而调整。遵循以下实践，让主题可翻译、可感知语言区域。

## 用翻译键代替硬编码文本

不要在模板里硬编码面向顾客的文本。把它们存进 [locale 文件](/zh-CN/docs/theme/architecture/locales/overview)，用 [`t` 过滤器](/zh-CN/docs/theme/references/liquid/filters/localization)输出。翻译键必须以 `i18n.` 为前缀：

```liquid
{{ 'i18n.products.product.add_to_cart' | t }}
```

在 `en-US.json` 里该键下设 `"add_to_cart": "Add to cart"`，这会渲染出 `Add to cart`；`fr.json` 里同一个键则渲染 `Ajouter au panier`，于是店铺前端按语言区域显示对应措辞。这样商家和译者无需改模板即可本地化你的主题。locale 文件格式与完整用法见[店铺前端 locale 文件](/zh-CN/docs/theme/architecture/locales/storefront-locale-files#使用说明)。

## 插值动态值

用命名参数把变量插入翻译，而不是拼接字符串：

```liquid
{{ 'i18n.cart.summary.item_count' | t: count: cart.item_count }}
```

locale 字符串里变量用双花括号包住，命名参数负责填入。locale 文件里写 `"item_count": "{{count}} items"`、购物车有 3 件时，这会渲染出 `3 items`。多个参数用逗号分隔：`| t: count: 3, name: 'Tom'`。

不支持基于数量的复数形态（如 `one`/`other` 对象）。当措辞随数字变化时，在 Liquid 中分支判断，并为每种形态用单独的键：

```liquid
{% if cart.item_count == 1 %}
  {{ 'i18n.cart.summary.item_count_one' | t }}
{% else %}
  {{ 'i18n.cart.summary.item_count_other' | t: count: cart.item_count }}
{% endif %}
```

## 检测当前语言

店铺当前语言区域可通过 [shop object](/zh-CN/docs/theme/references/liquid/objects/shop) 的 `shop.locale` 获取——例如 `en-US` 或 `ar-SA`。当行为需要依语言而定时使用它：

例如，按语言选择匹配的日期格式（这是 `t` 过滤器本身无法表达的）：

```liquid
{% assign date_format = '%b %d, %Y' %}
{% if shop.locale == 'ja-JP' %}{% assign date_format = '%Y年%m月%d日' %}{% endif %}
{{ 'now' | date: date_format }}
```

## 支持从右到左的语言

阿拉伯语、希伯来语等语言从右向左阅读。平台不会自动设置文字方向——必须由主题处理。在布局的 `<html>` 元素上，根据 `shop.locale` 设置 `dir` 属性：

```liquid
<html lang="{{ shop.locale }}"{% if shop.locale == 'ar-SA' %} dir="rtl"{% endif %}>
```

为主题支持的每种从右到左语言各加一个判断，并确保 CSS 能处理镜像布局——例如用 `margin-inline-start` 这类逻辑属性代替 `margin-left`。

## 优先使用原生翻译，而非前端控件

通过原生 locale 文件和 `t` 过滤器翻译主题。这些文本在服务端渲染，能被搜索引擎索引，并与页面其余部分保持一致。

第三方翻译控件（如谷歌翻译下拉框）在页面加载后于浏览器中覆盖翻译。它们安装快，但产出质量较低、不可被索引的文本。只把它们作为兜底，而非主要的本地化方案。
