即使applicatie internationaliseren
即使applicatie internationaliseren
见过甚至internationaal publiek是Symfonyob娱乐下载 vrijwel vanaf het开始在国家geweest om internationalisering (i18n) en lokalisatie (l10n) op甚至eenvoudige许多长te pakken。Het lokaliseren van甚至applicatie gaat不行alleen Het vertalen van de接口,Het gaat显得meervouden,基准——en valutaopmaak URL,米尔。
URL的internationaliseren
De eerste堵塞om De网站te internationaliseren het internationaliseren van De URL。Bij het vertalen van甚至网站接口,酩悦德URL verschillend zijn / locale, om去om te kunnen服务员遇到HTTP缓存(gebruik nooit dezelfde URL在sla德地区德sessie op)。
Gebruik de speciale_locale
routeparameter om te verwijzen naar德地区航线:
1 2 3 4 5 6 7 8 9 10 11
- - - / src /控制器/ ConferenceController.php+ + + b / src /控制器/ ConferenceController.php@@ -33 7 + 33 7 @@类ConferenceController AbstractController $ this - >扩展总线= $总线;}- #[路线(“/”,名字:“主页”))+ #[路线(“/ {_locale} /”,名字:“主页”))公共函数指数(ConferenceRepository ConferenceRepository美元):{$响应响应= new响应($ this - >树枝>渲染(会议/ index . html。嫩枝”,(
Op de主页wordt德地区νingesteld Op van de基础URL;bijvoorbeeld,人事处/ fr /
,geeft$请求- > getLocale ()
νfr
terug。
Omdat我waarschijnlijk不行在国家zult zijn om de inhoud naar阿莱geldige地区te vertalen, beperk我我合计地区死我必ondersteunen。
1 2 3 4 5 6 7 8 9 10 11
- - - / src /控制器/ ConferenceController.php+ + + b / src /控制器/ ConferenceController.php@@ -33 7 + 33 7 @@类ConferenceController AbstractController $ this - >扩展总线= $总线;}- #[路线(“/ {_locale} /”,名字:“主页”))+ #[路线(' / {_locale < en | fr >} / ',名字:“主页”))公共函数指数(ConferenceRepository ConferenceRepository美元):{$响应响应= new响应($ this - >树枝>渲染(会议/ index . html。嫩枝”,(
Elke routeparameter菅直人沃顿beperkt tussen门甚至正则表达式<
>
。德主页
路线komtνalleen钉低平火山口overeen als de_locale
参数在
的fr
是多少。探针/ es /
op te vragen,我邹甚至404 te虽然moeten krijgen omdat er overeenkomt geen路线。
在bijna Aangezien我们dezelfde vereiste阿莱路线zullen gebruiken, verplaatsen我们deze naar甚至containerparameter:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
- - - / config / services.yaml+ + + b / config / services.yaml@@ 7,6 + 7,7 @@参数:default_admin_email: admin@example.com default_domain: 127.0.0.1的default_scheme:“http”+ app.supported_locales:“en | fr”router.request_context。主持人:' % env(默认值:default_domain: SYMob娱乐下载FONY_DEFAULT_ROUTE_HOST) %的router.request_context。方案:' % env(默认值:default_scheme: SYMFONob娱乐下载Y_DEFAULT_ROUTE_SCHEME) % '- - - / src /控制器/ ConferenceController.php+ + + b / src /控制器/ ConferenceController.php@@ -33 7 + 33 7 @@类ConferenceController AbstractController $ this - >扩展总线= $总线;}- #[路线(' / {_locale < en | fr >} / ',名字:“主页”))+ #【路线(' / {_locale < %应用。supported_locales % >} /”,名字:“主页”)公共函数指数(ConferenceRepository ConferenceRepository美元):{$响应响应= new响应($ this - >树枝>渲染(会议/ index . html。嫩枝”,(
我们门德甚至Het toevoegen范塔阿尔多恩app.supported_languages
参数bij te威尔。
Voeg dezelfde河畔区域路由前缀脚趾de安德利果汁的网址:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
- - - / src /控制器/ ConferenceController.php+ + + b / src /控制器/ ConferenceController.php7 + 44 @@ -44年,7美元@@类ConferenceController扩展AbstractController返回响应;}- #[路线(“/ conference_header”,名字:“conference_header”))+ #【路线(' / {_locale < %应用。supported_locales % >} / conference_header”,名字:“conference_header”)公共函数conferenceHeader (ConferenceRepository ConferenceRepository美元):{$响应响应= new响应($ this - >树枝>渲染(会议/ header.html。枝”,[@@ -55 7 + 55岁,7美元@@类ConferenceController扩展AbstractController返回响应;}- #[路线(“/会议/{蛞蝓}”,名字:“会议”))+ #【路线(' / {_locale < %应用。supported_locales % >} /会议/{蛞蝓}”,名字:“会议”)公共函数显示(请求请求美元,美元会议,会议CommentRepository CommentRepository美元,美元NotifierInterface通知,字符串photoDir美元):反应{$评论=新的评论();
我们zijn bijna klaar。我们hebben geen路线米尔死overeenkomt满足/
。变迟我们deze我们ondersteunen en omleiden naar/ en /
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
- - - / src /控制器/ ConferenceController.php+ + + b / src /控制器/ ConferenceController.php@@ -33年33岁的6 + 12 @@类ConferenceController AbstractController $ this - >扩展总线= $总线;}+ #(路线(“/”))+公共职能indexNoLocale():反应+ {+ $ this - > redirectToRoute返回(“主页”,(“_locale”= >“en”));+}+#(路线(' / {_locale < %应用。supported_locales % >} /”,名字:“主页”)]公共函数指数(ConferenceRepository ConferenceRepository美元):反应{
νdat阿莱hoofdroutes voorzien zijn van de语境,zie我dat gegenereerde URL的op de pagina automatisch rekening houden de huidige地区。
即使语言环境切换器toevoegen
在国家te stellen van de standaard Om gebruikers在
地区naar甚至安德利果汁在te schakelen地区,voegen我们bovenin甚至脚趾切换器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
- - - /模板/ base.html.twig+ + + b /模板/ base.html.twig6 + 34 @@ -34年,16 @@李管理< / > < / >+ <李类= " nav-item拉" >+ < class = " nav-link dropdown-toggle " href = " # " id =“dropdown-language”角色=“按钮”+ data-bs-toggle =“下拉”aria-haspopup = " true " aria-expanded =“false”>+英语+ < / >+ < ul类= "下拉菜单dropdown-menu-right”aria-labelledby = " dropdown-language " >+ <李> < class = " dropdown-item " href = "{{路径(“主页”,{_locale:“en”})}} " > < / > < /李>英语+ <李> < class = " dropdown-item " href = "{{路径(“主页”,{_locale:“fr”})}} " > < / > < /李>法语+ < / ul >李+ < / >< / ul > < / div > < / div >
Om / te schakelen naar甚至安德利果汁语境,我们expliciet de算法_locale
河畔routeparameter门德路径()
functie。
更新de模板om de huidige地区拿安我们te判定在plaats van de硬编码waarde“英语”:
1 2 3 4 5 6 7 8 9 10 11
- - - /模板/ base.html.twig+ + + b /模板/ base.html.twig@@ -37年,37岁的7 + 7 @@<李class = " nav-item拉" > < class = " nav-link dropdown-toggle " href = " # " id =“dropdown-language”角色=“按钮”data-bs-toggle =“下拉”aria-haspopup = " true " aria-expanded =“false”>- - - - - -英语+ {{app.request.locale | locale_name (app.request.locale)}}< / > < ul类= "下拉菜单dropdown-menu-right”aria-labelledby = " dropdown-language " > <李> < class = " dropdown-item " href = "{{路径(“主页”,{_locale:“en”})}} " > < / > < /李>英语
应用程序
即使是这个整体Twig-variabele死toegang geeft合计de huidige请求。Om德地区Om te zetten naar甚至menselijk leesbare字符串,我们德Twig-filter gebruikenlocale_name
。
Afhankelijk van de地区wordt de localenaam不行altijd见面甚至hoofdletter geschreven。Om op de juiste许多Om te hoofdletters会面,服务员hebben我们甚至过滤器nodig死Unicode-bewust, zoals de Symfony String-component eob娱乐下载n de Twig-implementatie ervan:
1
美元ob娱乐下载symfony作曲家点播树枝/ string-extra
1 2 3 4 5 6 7 8 9 10 11
- - - /模板/ base.html.twig+ + + b /模板/ base.html.twig@@ -37年,37岁的7 + 7 @@<李class = " nav-item拉" > < class = " nav-link dropdown-toggle " href = " # " id =“dropdown-language”角色=“按钮”data-bs-toggle =“下拉”aria-haspopup = " true " aria-expanded =“false”>- {{app.request.locale | locale_name (app.request.locale)}}+ {{app.request.locale | locale_name (app.request.locale) | u。标题}}< / > < ul类= "下拉菜单dropdown-menu-right”aria-labelledby = " dropdown-language " > <李> < class = " dropdown-item " href = "{{路径(“主页”,{_locale:“en”})}} " > < / > < /李>英语
我kuntνwisselen van Frans de台湾加高naar恩格斯en接口过去zich netjes长:
Vertalen van de接口
Het vertalen van elke寻op甚至格罗特网站甚至台湾加高klus,低平火山口gelukkig hebben我们低平火山口甚至handvol berichten op onze网站。变迟我们beginnen见过阿莱zinnen op de主页:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30 31
- - - /模板/ base.html.twig+ + + b /模板/ base.html.twig7 @@ @@ -20年7 + 20日<导航类= "导航navbar-expand-xl navbar-light bg-light”> < div class = "容器mt-4 mb-3”> < class = " navbar-brand我pr-2 " href = "{{路径(主页)}}" >- & # 128217;会议留言板+ & # 128217;{{“会议留言板”|反式}}< / > <按钮类= " navbar-toggler border-0 " type = "按钮" data-bs-toggle =“崩溃”data-bs-target = " # header-menu " aria-controls =“navbarSupportedContent aria-expanded”=“false”aria-label = "显示/隐藏导航" >- - - /模板/会议/ index.html.twig+ + + b /模板/会议/ index.html.twig@@ 4、7 + 4,7 @@{%块体%}< h2类= " mb-5 " >——给你的反馈!+{{'给你的反馈!“|反式}}< / h2 >{%在会议|行批处理(4)%}7 @@ @@ -21年7 + 21日< a href = "{{路径(“会议”,{蛞蝓:会议。蛞蝓})}}”class = " btn btn-sm btn-primary stretched-link " >——视图+{{‘视图’|反式}}< / > < / div > < / div >
德反式
Twig-filter zoekt甚至vertaling van de gegeven其naar de huidige地区。印度不行gevonden, valt het terug naar destandaard语言环境zoals geconfigureerd在配置/包/ translation.yaml
:
1 2 3 4 5 6
框架:default_locale:在翻译:default_path:' % kernel.project_dir % /翻译'回退:- - - - - -在
默克op dat het vertaling tabblad“van de web调试工具栏十字架geworden:
Het vertelt ons dat er 3 berichten钉不行vertaald zijn。
公里op de”选项卡“om阿莱berichten te tonen waarvoor Symfony gob娱乐下载een vertaling heeft gevonden:
Vertalingen ondersteunen
Zoals我misschien al gezien hebt配置/包/ translation.yaml
甚至,沃顿vertalingen opgeslagen翻译/
hoofdmap,死automatisch voor ons aangemaakt。
在plaats van de vertaalbestanden遇到德河畔手te梅根,gebruik我het翻译:提取
突击队:
1
美元ob娱乐下载symfony控制台翻译:提取fr -力-域=消息
甚至说特种兵genereert vertaalbestand (——力
vlag) voor德fr
语言环境在het消息
domein。Het消息
domein bevat阿莱applicatieberichten, behalve degene死外的Symfonob娱乐下载y zelf科曼zoals validatie beveiligingsfouten。
Bewerk het翻译/消息+ intl-icu.fr.xlf
bestand en vertaal het Frans de berichten。Spreek我geen弗兰斯?Laat我我helpen:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
- - - /翻译/消息+ intl-icu.fr.xlf+ + + + intl-icu.fr.xlf b /翻译/消息15 @@ @@ 7日15 + 7,<身体> < trans-unit id = " eOy4.6V " resname = "会议留言板" > <源>会议留言板源> < /- <目标> __Conference留言板目标> < /+ <目标>里弗d ' or倒会议目标> < /< / trans-unit > < trans-unit id = " LNAVleg " resname = "给你的反馈!> <源>给你反馈! > < /来源——<目标> __Give你反馈! < /目标>+ <目标> Donnez你们认为! < /目标>< / trans-unit > < trans-unit id =“3 mg5paf”resname =“视图”> <源>视图> < /来源- <目标> __View目标> < /+ <目标>选择目标> < /< / trans-unit > < /身体> < /文件>
默克op dat我们不行阿莱模板zullen vertalen,低平火山口voel我vrij om说逢te多恩:
Vertalen van formulieren
Formulierlabels沃顿门Symfony auob娱乐下载tomatisch middel van het vertaalsysteem weergegeven大门。Ga naar甚至conferentiepagina en公里op het“Vertaling tabblad van de web调试工具栏;我邹阿莱标签死beschikbaar zijn voor vertaling moeten虽然早:
Lokaliseren van论据
Als我overschakelt naar Frans en甚至conferentiepagina遇到reacties bezoekt, zul我虽然dat de基准面van de reacties automatisch gelokaliseerd zijn。我们说werkt omdat de树枝format_datetime
过滤器gebruikt hebben死op de hoogte范地区({{发表评论。createdAt | format_datetime(“媒介”,“短”)}}
)。
De lokalisatie werkt voor论据,tijden (format_time
)、币值(format_currency
)en getallen (format_number
在het)刊登(procenten duurtijden,拼写,....)。
Vertalen van meervouden
Het vertalen van meervouden是即使voorbeeld van甚至algemener probleem, waarbij我甚至vertaling酩悦selecteren op van甚至voorwaarde基础。
Op甚至conferentiepagina tonen我们het aantal reacties:有两个评论
。我们foutief Voor 1中tonen活化有1的评论
。Wijzig de模板zodat de寻om te zetten在即使vertaalbaar bericht:
1 2 3 4 5 6 7 8 9 10 11
- - - /模板/会议/ show.html.twig+ + + b /模板/会议/ show.html.twig7 + 44 @@ -44年,7 @@< / div > < / div > {% endfor %}——< div >有{{评论|长度}}评论。< / div >+ < div > {{“nb_of_comments”|反式({长度数:评论|})}}< / div >{%如果先前> = 0%}< a href = "{{路径(“会议”,{蛞蝓:会议。蛞蝓,抵消:以前})之前}}" > < / > {% endif %}
Voor deze boodschap hebben我们甚至安德利果汁vertaalstrategie gebruikt。在plaats van de Engelse versie de模板中te behouden, hebben我们deze vervangen门甚至unieke标识符。死的那个werkt打赌voor complexe恩格罗特hoeveelheden tekst。
更新het vertaalbestand门het nieuwe bericht脚趾te voegen:
1 2 3 4 5 6 7 8 9 10 11 12 13
- - - /翻译/消息+ intl-icu.fr.xlf+ + + + intl-icu.fr.xlf b /翻译/消息10 @@ @@ -17年6 + 17日<源>会议留言板< /源> <目标>里弗d ' or倒会议< /目标> < / trans-unit >+ < trans-unit id = " Dg2dPd6“resname = " nb_of_comments " >+ <源> nb_of_comments源> < /+ <目标>{数、复数、= 0{没有commentaire。{1 commentaire} = 1。}other {# commentaires.}}< /span>+ < / trans-unit >< /身体> < /文件> < / xliff >
我们zijn钉不行klaar, omdat我们νde Engelse vertaling钉moeten ondersteunen。Maak het翻译/消息+ intl-icu.en.xlf
bestand长:
Functionele测试bijwerken
Vergeet不行om de functionele测试bij te威尔门URL的en inhoudelijke wijzigingen te nemen:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30 31 32 33 34 35 36 37
- - - /测试/控制器/ ConferenceControllerTest.php+ + + b /测试/控制器/ ConferenceControllerTest.php@@ -11 7 + 11 7 @@类ConferenceControllerTest WebTestCase延伸公共函数testIndex(){$客户=静态:createClient ();-客户- >请求(‘得到’,‘/’);+ $客户- >请求(‘得到’,' / en / ');$ this - > assertResponseIsSuccessful ();$ this - > assertSelectorTextContains (h2,给你反馈);@@ -20 7 + 20 7 @@类ConferenceControllerTest WebTestCase延伸公共函数testCommentSubmission(){$客户=静态:createClient ();-客户- >请求(‘得到’,' /会议/阿姆斯特丹- 2019 ');+ $客户- >请求(‘得到’,‘/ en /会议/阿姆斯特丹- 2019);$客户- > submitForm(‘提交’,‘comment_form(作者)”= >“法”,“comment_form[文本]= >从自动化功能测试的一些反馈,@@ -41年7 + 41,7 @@类ConferenceControllerTest WebTestCase延伸公共函数testConferencePage(){$客户=静态:createClient ();-履带=美元客户- >请求(‘得到’,‘/’);+ $履带= $客户- >请求(‘得到’,' / en / ');$ this - > assertCount(2 $履带- >过滤器(h4));@@ -50 50 6 + 6 @@类ConferenceControllerTest延伸WebTestCase $ this - > assertPageTitleContains(阿姆斯特丹);$ this - > assertResponseIsSuccessful ();$ this - > assertSelectorTextContains (h2,阿姆斯特丹2019);- $ this - > assertSelectorExists (“div:包含(“有1评论”)');+ $ this - > assertSelectorExists (“div:包含(“有一个评论”)');}}