Silex中TranslationServiceProvider的基本用法

时间:2014-08-25 09:30:57

标签: translation silex

我试图以最直接的方式使用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' (??)

我使用提供商的方式有什么问题?

2 个答案:

答案 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)

关于拉尔夫回答的两点评论:

  1. 几乎所有在before()中间件中完成的操作都是不必要的,因为Request类提供了一种基于“Accept-Language”标头确定“最佳”语言的便捷方法。所以基本上,只需要这个:

    $app->before(
        function (Request $request) use ($app) {
            $app['translator']->setLocale($request->getPreferredLanguage(['en', 'fr']));
        }
    );
    
  2. Silex在路由定义中使用“magic”变量“{_locale}”来相应地设置语言环境。这意味着您既不需要在实例化TranslationServiceProvider时声明语言环境,也不需要调用setLocale(),而只是声明这样的路由:

    $app->get('/{_locale}/path', ...);
    
  3. 现在,Twig和$app['translator'](在Closure或控制器方法中)将自动设置为正确的语言环境。