yao/sui/docs/i18n.md
Max f115e6d782 Update Documentation for SUI Structure and Locale Handling
- Revised the README and agent-sui documentation to clarify the directory structure, including the addition of __data.json and __locales directories for global and page-level data.
- Enhanced explanations of the pages directory, emphasizing the organization of global and assistant-specific pages.
- Updated the i18n documentation to detail locale detection and the importance of server-side rendering for translations, including a code snippet for changing locales via JavaScript.
2026-01-03 15:06:32 +08:00

295 lines
5.8 KiB
Markdown

# Internationalization (i18n)
SUI provides built-in support for internationalization with translation markers and locale files.
## Translation Markers
### Static Text
Use `s:trans` attribute for static text:
```html
<span s:trans>Hello World</span>
<button s:trans>Submit</button>
<p s:trans>Welcome to our application</p>
```
### In Expressions
Use `'::'` prefix in expressions:
```html
<span>{{ '::Welcome' }}</span>
<span>{{ '::Hello, ' + name }}</span>
<p>{{ '::You have ' + count + ' messages' }}</p>
```
### In Scripts
Use `__m()` function:
```html
<script>
const message = __m("Welcome back");
const greeting = __m("Hello, ") + userName;
alert(__m("Are you sure?"));
</script>
```
## Locale Files
### Directory Structure
```
/templates/<template>/
└── __locales/
├── en-us/
│ ├── home.yml
│ └── users/list.yml
└── zh-cn/
├── home.yml
└── users/list.yml
```
### File Format
**`__locales/zh-cn/home.yml`**:
```yaml
name: zh-cn
direction: ltr
timezone: +08:00
formatter: scripts.locale
messages:
Hello World: 你好世界
Welcome: 欢迎
"Hello, ": "你好,"
Submit: 提交
"You have %d messages": "你有 %d 条消息"
keys:
page_title: 首页
nav_home: 首页
nav_about: 关于
script_messages:
Welcome back: 欢迎回来
"Are you sure?": "你确定吗?"
```
### Sections
| Section | Description |
| ----------------- | ----------------------------------- |
| `name` | Locale identifier |
| `direction` | Text direction (`ltr` or `rtl`) |
| `timezone` | Timezone offset |
| `formatter` | Custom formatter process |
| `messages` | Translations for `s:trans` and `::` |
| `keys` | Named translation keys |
| `script_messages` | Translations for `__m()` |
## Using Translations
### HTML Templates
```html
<!-- Static translation -->
<h1 s:trans>Welcome to our site</h1>
<!-- Dynamic translation -->
<p>{{ '::Hello, ' + user.name }}</p>
<!-- With variables -->
<span>{{ '::You have ' + count + ' items' }}</span>
```
### Named Keys
Named keys are used internally for translation lookup. The `keys` section in locale files provides named references for translations that can be used programmatically.
### Scripts
```typescript
import { Component } from "@yao/sui";
const self = this as Component;
self.ShowMessage = () => {
const message = __m("Operation completed");
alert(message);
};
self.Confirm = () => {
return confirm(__m("Are you sure you want to delete?"));
};
```
## Locale Detection
SUI detects locale from the `locale` HTTP cookie on the server side.
**Important:** `s:trans` translations are server-side rendered. This means:
1. The translation happens when the page is generated on the server
2. Changing locale via JavaScript only affects localStorage/client state
3. To apply locale changes to `s:trans` content, you must reload the page
```javascript
// To change locale and have s:trans reflect the change:
document.cookie = "locale=zh-CN;path=/;max-age=31536000";
location.reload(); // Required for server-side translations
```
**Cookie Priority:**
1. `locale` cookie (primary)
2. `umi_locale` cookie (fallback for CUI compatibility)
3. Browser language
4. Default (`en-us`)
### Access Current Locale
```html
<html lang="{{ $locale }}">
<body dir="{{ $direction }}">
...
</body>
</html>
```
## Custom Formatter
Define a custom formatter process:
```yaml
# In locale file
formatter: scripts.locale.format
```
**`scripts/locale.js`**:
```javascript
function format(text, args) {
// Custom formatting logic
return text.replace(/%d/g, () => args.shift());
}
```
## RTL Support
For right-to-left languages:
```yaml
# __locales/ar/home.yml
name: ar
direction: rtl
timezone: +03:00
messages:
Hello: مرحبا
```
```html
<body dir="{{ $direction }}">
<!-- Content automatically flows RTL -->
</body>
```
## Building Translations
### Generate Translation Files
```bash
yao sui trans <sui> <template>
```
This command:
1. Scans all pages for translation markers
2. Generates/updates locale files
3. Builds the template
### Translation Workflow
1. Add `s:trans` or `::` markers to your HTML
2. Run `yao sui trans` to extract strings
3. Edit locale files to add translations
4. Build with `yao sui build`
## Complete Example
**`/home/home.html`**:
```html
<div class="home">
<h1 s:trans>Welcome to our application</h1>
<p>{{ '::Hello, ' + user.name }}</p>
<div class="stats">
<span>{{ '::You have ' + messageCount + ' messages' }}</span>
</div>
<nav>
<a href="/" s:trans>Home</a>
<a href="/about" s:trans>About</a>
<a href="/contact" s:trans>Contact</a>
</nav>
<button s:on-click="ShowWelcome" s:trans>Show Welcome</button>
</div>
<script>
import { Component } from "@yao/sui";
const self = this as Component;
self.ShowWelcome = () => {
alert(__m("Welcome to our site!"));
};
</script>
```
**`__locales/zh-cn/home.yml`**:
```yaml
name: zh-cn
direction: ltr
timezone: +08:00
messages:
Welcome to our application: 欢迎使用我们的应用
"Hello, ": "你好,"
"You have ": "你有 "
" messages": " 条消息"
Home: 首页
About: 关于
Contact: 联系我们
Show Welcome: 显示欢迎
script_messages:
"Welcome to our site!": "欢迎来到我们的网站!"
```
**`__locales/ja/home.yml`**:
```yaml
name: ja
direction: ltr
timezone: +09:00
messages:
Welcome to our application: アプリケーションへようこそ
"Hello, ": "こんにちは、"
"You have ": ""
" messages": " 件のメッセージがあります"
Home: ホーム
About: について
Contact: お問い合わせ
Show Welcome: ようこそを表示
script_messages:
"Welcome to our site!": "私たちのサイトへようこそ!"
```