7: 翻译
Phlo 将翻译视为渲染问题:您在源语言中编写视图文本,进行标记,lang 资源在请求时提供正确的语言,并在后台翻译缺失的条目。在本章中,投票在 /nl 前缀下学习荷兰语。
7.1: 源语言标记
静态视图文本会根据文本所写的语言获取一个标记。该应用的源语言是英语,因此键是 en:
view:
<main#app.poll>
<h1>{en: Which stack wins?}</h1>
{{ $this->results }}
{{ $this->choices }}
</main>
{en: ...} 编译为对 en() 辅助函数的调用,该函数向翻译层请求活动语言中的文本。如果活动语言是英语,则文本将原样通过。如果您正在编写一个荷兰语源的应用,您将使用 {nl: ...},其机制相同;标记始终命名该特定字符串的源语言。在视图之外,相同的辅助函数在代码中也能工作:method title => en('Phlo Poll')。
现在更新 poll.phlo 中的 <h1>;页面仍然呈现相同,因为活动语言仍然是英语。
7.2: 配置语言层
三个小配置。首先,data/app.json 中的资源(lang 资源带来了 cookie 检测、INI 文件缓存和 AI 支持的翻译):
{
"resources": [
"DB/DB",
"DB/model",
"DB/JSONDB",
"DB/JSON.result",
"payload",
"phlo.async",
"DOM/form",
"lang",
"cookies",
"files/INI",
"AI/AI",
"AI/OpenAI",
"security/creds"
]
}
其次,在 www/app.php 中告诉运行时翻译文件的位置:
phlo_app(
id: 'Poll',
host: 'localhost',
build: true,
debug: true,
app: dirname(__DIR__).'/',
langs: dirname(__DIR__).'/langs/',
);
传递给 phlo_app() 的每个命名参数都成为应用程序范围的常量,因此 langs 现在是您(和 lang 资源)可以在任何地方使用的路径。创建文件夹:mkdir app/langs。
第三,在 app.phlo 中声明应用程序的语言:
prop lang = 'en'
prop langs = ['en' => 'English', 'nl' => 'Nederlands']
重新构建并进行 lint;两者都以 [] 结束。
7.3: 一个 /nl 路由前缀
活动语言存储在 %app->lang 中。可以通过在 poll.phlo 中设置第二个路由来从 URL 中设置它:
route GET poll => $this->home
route GET $lang:nl poll {
%app->lang = $lang
$this->home
}
$lang:nl 是一个值列表段:只有当第一个路径段字面上是 nl 时,它才会匹配。要添加更多语言,可以扩展列表:$lang:nl,de,fr。英语路由保持干净的 URL;带前缀的路由设置语言并渲染相同的页面。
打开 http://localhost/nl/poll。<html lang="nl"> 属性遵循 %app->lang,但标题仍然是英语:尚未有荷兰语翻译。
7.4: 翻译缓存
翻译存储在 langs/<lang>.ini 中,每个字符串占一行,按源文本的哈希值进行键控。当一个标记字符串在活动语言中没有条目时,页面会显示源文本并通过 OpenAI 安排后台翻译;下一个请求会读取缓存结果。为了使该回填工作正常,请在 data/creds.ini 中放入 API 密钥:
OpenAI = sk-...
没有密钥?一切仍然可以正常工作,缺失的字符串将保持在源语言中。您也可以自己编写文件;在第一次回填后,langs/nl.ini 看起来像这样:
enWhichStad3 = "Welke stack wint?"
该键编码了源语言加上确切文本的哈希值,因此更改的源文本会获得一个新的条目。条目存在后,请重新加载 http://localhost/nl/poll:
<h1>Welke stack wint?</h1>
相同的视图,相同的路由逻辑,第二种语言。投票距离完成还有一章:它仍然无法将结果推送给其他查看者。