ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Yao SUI 国际化(i18n)完整指南:翻译标记、语言包目录与 locale 检测机制

Yao SUI 国际化(i18n)完整指南:翻译标记、语言包目录与 locale 检测机制 Agent 框架后端低代码RAG【免费下载链接】yao✨ All your agents and workspaces in one place, on every device you own. Track tasks on a board, accessible from desktop, mobile, browser, or API. Self-hosted.项目地址https://gitcode.com/gh_mirrors/ya/yao点击查看免费下载Yao 低代码平台的 SUI 前端框架内置了一套完整、服务端渲染优先的国际化i18n方案通过在 HTML 模板中插入s:trans、::表达式前缀和__m()脚本函数三类翻译标记配合模板目录下的__locales语言包文件即可让一个模板同时输出多语言页面。本文基于仓库文档 sui/docs/i18n.md并结合 sui/core/locale.go、sui/core/translate.go、sui/core/request.go 等源码实现完整讲解翻译标记的三种用法、语言包目录与文件格式、locale 的 Cookie 检测优先级、自定义 formatter、RTL 支持以及yao sui trans的提取与构建工作流。一、三种翻译标记静态文本、表达式与脚本SUI 的翻译体系围绕三类场景设计了三种标记分别覆盖 HTML 静态文本、{{ }}表达式插值、以及script脚本逻辑中的文案。1. 静态文本s:trans属性在任意 HTML 元素上添加s:trans属性元素内的纯文本内容就会被标记为可翻译文案span s:transHello World/span button s:transSubmit/button p s:transWelcome to our application/p从源码实现看这一标记由 sui/core/translate.go 中的translateNode处理当解析器遍历到文本节点html.TextNode时会检查其父节点是否带有s:trans属性若存在则把文本内容去除首尾空白收集为一个Translation{Key, Message, Type: text}记录并给父节点写入s:trans-node与s:trans-escape标记后续由渲染管线按 locale 替换输出。2. 表达式内翻译::前缀在{{ }}数据绑定表达式中用::前缀包裹的字符串字面量会被识别为翻译条目可与变量、表达式自由拼接span{{ ::Welcome }}/span span{{ ::Hello, name }}/span p{{ ::You have count messages }}/p对应的正则匹配定义在 sui/core/build.go 中var transStmtReSingle regexp.MustCompile(::([^:])) var transStmtReDouble regexp.MustCompile(::([^:]))即同时支持单引号::...与双引号::...两种写法命中后原文内容如Hello,、You have会被抽取为翻译消息。3. 脚本内翻译__m()函数在script或 TypeScript 组件脚本中使用全局函数__m(...)获取翻译后的文案script const message __m(Welcome back); const greeting __m(Hello, ) userName; alert(__m(Are you sure?)); /script源码中translateScript使用正则transFuncRe扫描脚本源码匹配__m(...)同时也兼容裸调用的T(...)调用并提取引号内的字符串作为Type: script的翻译条目见 sui/core/build.go 与 sui/core/translate.go。二、语言包Locale Files目录结构、文件格式与分区说明1. 目录结构每个模板在自身根目录下维护一个__locales目录按语言代码分文件夹每个语言包内按页面路由镜像目录结构/templates/template/ └── __locales/ ├── en-us/ │ ├── home.yml │ └── users/list.yml └── zh-cn/ ├── home.yml └── users/list.yml其中users/list.yml对应页面路由users/list。源码 sui/core/locale.go 中的Locale()方法正是把请求的路由拼接为public/root/.locales/locale/route.yml进行查找并内置了三级回退先尝试精确 locale如zh-cn再回退到语言前缀zh-cn→zh最后回退到en-us。2. 文件格式与分区语言包是 YAML 文件整体结构如下示例__locales/zh-cn/home.ymlname: 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?: 你确定吗各分区含义如下表Section说明name语言标识符如zh-cn、en-usdirection文本方向取值为ltr从左到右或rtl从右到左timezone时区偏移如08:00缺省时由GetSystemTimezone()自动取系统时区formatter自定义格式化处理器进程名可选messages供s:trans与::表达式使用的翻译映射keys具名翻译键named keys供程序化引用script_messages供__m()脚本函数使用的翻译映射这些分区与源码中的Locale结构体一一对应定义于 sui/core/types.gotype Locale struct { Name string yaml:name,omitempty Formatter string yaml:formatter,omitempty Keys map[string]string yaml:keys,omitempty Messages map[string]string yaml:messages,omitempty ScriptMessages map[string]string yaml:script_messages,omitempty Direction string yaml:direction,omitempty Timezone string yaml:timezone,omitempty }需要说明的是direction与timezone在加载后会被写入渲染数据$direction、$timezone供模板中的dir属性与日期格式化使用。3. 翻译条目的自动键Named Keys 的底层机制文档说明 named keys 用于内部翻译查找。结合源码 sui/core/locale.go 的MergeTranslations与 sui/core/utils.go 的TranslationKey可以看到每次提取到一条翻译消息都会按trans_路由_序号的规则生成内部键例如trans_home_0并将其写入keys区ParseKeys()则负责在语言包加载后把keys中的值解析为messages区对应的真实译文。也就是说keys区既支持开发者手写的具名键如page_title也会被自动生成的翻译键填充二者统一参与查找。三、HTML 模板与脚本中的实际用法1. HTML 模板组合使用!-- Static translation -- h1 s:transWelcome to our site/h1 !-- Dynamic translation -- p{{ ::Hello, user.name }}/p !-- With variables -- span{{ ::You have count items }}/span注意::前缀只标记静态片段动态变量user.name、count仍在表达式层拼接翻译条目需按片段拆分例如Hello, 与You have 是独立的消息。2. 脚本中使用__m()与组件方法结合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 检测Cookie 优先级与服务端渲染要点1. 检测顺序SUI 在服务端从 HTTP 请求的 Cookie 中读取语言优先级从高到低localeCookie首选umi_localeCookieCUI 兼容回退浏览器语言默认语言en-us源码侧sui/core/request.go 的GetLocale只读取名为locale的 Cookie 并将其转为小写随后在NewData()中写入$locale等渲染变量而 sui/core/locale.go 的Locale()方法再按该值加载对应语言包未命中时按语言前缀与en-us逐级回退与文档中的优先级描述吻合。2. 重要s:trans是服务端渲染的必须理解的关键点s:trans的翻译发生在服务端生成页面 HTML 的时刻因此翻译在页面生成时完成s:trans内容是服务端渲染结果仅通过 JavaScript 修改本地状态/localStorage不会改变s:trans内容要让s:trans生效新的语言必须重新加载页面。推荐的切换语言方式// To change locale and have s:trans reflect the change: document.cookie localezh-CN;path/;max-age31536000; location.reload(); // Required for server-side translations3. 在模板中访问当前 locale渲染数据中已内置$locale与$direction可直接用于html的lang属性与body的dir属性html lang{{ $locale }} body dir{{ $direction }} ... /body /html五、自定义 Formatter扩展数字与文本格式化语言包中的formatter字段可指向一个自定义后端进程用于对翻译结果做进一步格式化如数字本地化、占位符替换。配置方式# In locale file formatter: scripts.locale.format对应的后端脚本scripts/locale.jsfunction format(text, args) { // Custom formatting logic return text.replace(/%d/g, () args.shift()); }源码实现见 sui/core/locale.go 的Fmt方法它以formatter.name拼出进程名调用process.Of(pname, value, ...)并额外传入name、timezone、direction三个上下文参数执行结果必须返回字符串否则回退原值。六、RTL从右到左语言支持为阿拉伯语等从右到左语言创建语言包时只需设置direction: rtl其余翻译逻辑完全一致# __locales/ar/home.yml name: ar direction: rtl timezone: 03:00 messages: Hello: مرحبا页面中通过dir绑定实现自动 RTL 排版body dir{{ $direction }} !-- Content automatically flows RTL -- /bodydirection在语言包加载后自动写入渲染数据$direction缺省为ltr见 sui/core/locale.go 的Locale()方法。七、翻译提取与构建yao sui trans工作流1. 命令用法yao sui trans sui template该命令定义于 cmd/sui/trans.go其执行流程为扫描模板内所有页面的翻译标记s:trans、::、__m()生成/更新各语言包的 locale 文件含keys自动键与messages/script_messages映射随后自动构建模板构建选项默认SSR: true并开启脚本/样式压缩--debug/-D可切换为开发模式不压缩。命令行还提供以下参数--data/-d会话数据JSON 字符串默认::{}会写入临时会话供模板渲染--debug/-D调试模式输出开发模式构建结果--locales/-l逗号分隔的语言列表只对指定语言执行翻译例如yao sui trans app home --locales zh-cn,en-us。2. 完整翻译工作流在 HTML 中添加s:trans或::标记运行yao sui trans提取文案并生成/更新语言包编辑__locales/locale/route.yml补全各语言译文使用yao sui build重新构建模板让新语言包生效。八、完整示例多语言首页以下是一个完整的多语言首页实现。/home/home.html模板页面混合使用三种翻译标记div classhome h1 s:transWelcome to our application/h1 p{{ ::Hello, user.name }}/p div classstats span{{ ::You have messageCount messages }}/span /div nav a href/ s:transHome/a a href/about s:transAbout/a a href/contact s:transContact/a /nav button s:on-clickShowWelcome s:transShow 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.ymlname: 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.ymlname: 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!: 私たちのサイトへようこそ九、实现原理小结整个 i18n 链路可以归纳为三个阶段提取Extractsui/core/translate.go 遍历 DOM 节点与脚本源码用 sui/core/build.go 中定义的正则transStmtReSingle、transStmtReDouble、transFuncRe识别三类翻译标记生成Translation条目合并与加载Merge Loadsui/core/locale.go 的MergeTranslations将提取结果合并进语言包keys/messages/script_messages渲染时Locale()按请求 Cookie 定位语言包并按语言前缀、en-us顺序回退语言包在内存中按Locale缓存可通过 Preview/Debug/Editor 模式绕过缓存渲染Rendermessages作用于s:trans与::表达式服务端渲染script_messages通过__m()在客户端脚本中生效formatter由 sui/core/locale.go 的Fmt调用后端进程做最终格式化。掌握这三条链路后你可以在 Yao SUI 模板中快速落地多语言站点先用yao sui trans自动提取文案再按语言维护__locales下的 YAML 语言包最后通过localeCookie 驱动服务端渲染完成整站切换。赞分享Agent 框架后端低代码RAG【免费下载链接】yao✨ All your agents and workspaces in one place, on every device you own. Track tasks on a board, accessible from desktop, mobile, browser, or API. Self-hosted.项目地址https://gitcode.com/gh_mirrors/ya/yao点击查看免费下载相关推荐Yao Agent 多语言国际化i18n完整指南Locale 文件、模板翻译与回退机制Yao Agent 多语言国际化i18n完整指南Locale 文件、模板翻译与回退机制 Yao 的 Agent 子系统内置了一套完整的国际化i18n方Agent 框架后端低代码RAGKubernetes Dashboard 国际化i18n完整指南语言检测、翻译流程与新语言接入Kubernetes Dashboard 国际化i18n完整指南语言检测、翻译流程与新语言接入 本指南以 Kubernetes Dashboard 仓库中前端后端云原生Yii 2 国际化I18N实战指南Locale 配置、消息翻译与多语言格式化Yii 2 国际化I18N实战指南Locale 配置、消息翻译与多语言格式化 本文以 Yii 2 框架的国际化Internationalisation,后端Web框架上一篇Parallax Pager与ViewPager深度整合实现无缝循环滚动下一篇洛雪音乐音源终极配置指南3分钟解锁全网无损音乐体验创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表