我试图以最直接的方式使用Silex TranslationServiceProvider,即
<?php
// web/index.php
require_once __DIR__.'/../vendor/autoload.php';
$app = new Silex\Application();
$app->register(new Silex\Provider\TranslationServiceProvider(), array(
'locale' => 'fr',
'locale_fallbacks' => array('en')
));
$app['translator.domains'] = array(
'messages' => array(
'en' => array('message_1' => 'Hello!'),
'fr' => array('message_1' => 'Bonjour')
));
echo $app['translator']->trans('message_1');
// I get 'Hello!' (why ?)
似乎没有考虑初始化TranslationServiceProvider时的'locale' => 'fr'
行,并且唯一重要的参数是locale_fallbacks
(当我将locale_fallbacks更改为'fr'
时,消息是用法语显示)
我在这里缺少一些非常简单的东西吗?
提前致谢
修改
当我使用setLocale
功能时,它仍然不起作用,似乎覆盖了locale_fallbacks
:
$app->register(new Silex\Provider\TranslationServiceProvider(), array(
'locale_fallbacks' => array('en')
));
$app['translator']->setLocale('fr');
echo $app['translator']->getLocale(); // returns 'fr' as expected
$app['translator.domains'] = array(
'messages' => array(
'en' => array('message_1' => 'Hello!'),
'fr' => array('message_1' => 'Bonjour')
));
echo $app['translator']->trans('message_1');
// now returns 'message_1' (??)
我使用提供商的方式有什么问题?
答案 0 :(得分:3)
您必须设置区域设置,否则使用后备:
$app['translator']->setLocale('fr');
我在$app->before()
处理程序中设置语言环境:
$app->before(function(Request $request) use ($app) {
// default language
$locale = 'en';
// quick and dirty ... try to detect the favorised language - to be improved!
if (!is_null($request->server->get('HTTP_ACCEPT_LANGUAGE'))) {
$langs = array();
// break up string into pieces (languages and q factors)
preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i',
$request->server->get('HTTP_ACCEPT_LANGUAGE'), $lang_parse);
if (count($lang_parse[1]) > 0) {
foreach ($lang_parse[1] as $lang) {
if (false === (strpos($lang, '-'))) {
// only the country sign like 'de'
$locale = strtolower($lang);
} else {
// perhaps something like 'de-DE'
$locale = strtolower(substr($lang, 0, strpos($lang, '-')));
}
break;
}
}
$app['translator']->setLocale($locale);
$app['monolog']->addDebug('Set locale to '.$locale);
}
});
答案 1 :(得分:1)
关于拉尔夫回答的两点评论:
几乎所有在before()中间件中完成的操作都是不必要的,因为Request类提供了一种基于“Accept-Language”标头确定“最佳”语言的便捷方法。所以基本上,只需要这个:
$app->before(
function (Request $request) use ($app) {
$app['translator']->setLocale($request->getPreferredLanguage(['en', 'fr']));
}
);
Silex在路由定义中使用“magic”变量“{_locale}”来相应地设置语言环境。这意味着您既不需要在实例化TranslationServiceProvider
时声明语言环境,也不需要调用setLocale()
,而只是声明这样的路由:
$app->get('/{_locale}/path', ...);
现在,Twig和$app['translator']
(在Closure或控制器方法中)将自动设置为正确的语言环境。