2011-10-07 100 views

回答

11

你需要調用$this->get('session')->setLocale($locale)控制器內(由Symfony的2.1 '請求' 代替 '會話')。

我創建了一個表格,而我通過語言的數組:

<?php 
class LanguageType extends AbstractType 
{ 
    public function buildForm(FormBuilder $builder, array $options) 
    { 
     $langs = $options['languages']; 
     $langs = array_combine($langs, $langs); 
     foreach ($langs as &$lang) { 
      $lang = \Locale::getDisplayName($lang); 
     } 

     $builder->add('language', 'choice', array(
      'choices' => $langs, 
      'required' => false, 
     )); 
    } 

    public function getDefaultOptions(array $options) 
    { 
     return array(
      'languages' => array('fr_FR', 'en_GB'), 
      'csrf_protection' => false, 
     ); 
    } 

    public function getName() 
    { 
     return 'my_language'; 
    } 
} 

我提交此表到一個單獨的動作在控制器中,我設定的區域,並返回一個重定向最後一頁:

<?php 
class LanguageController extends Controller 
{ 
    public function switchLanguageAction() 
    { 
     $form = $this->get('form.factory')->create(
      new LanguageType(), 
      array('language' => $this->get('session')->getLocale()), 
      array('languages' => $this->container->getParameter('roger.admin.languages', null)) 
     ); 

     $request = $this->get('request'); 
     $form->bindRequest($request); 
     $referer = $request->headers->get('referer'); 

     if ($form->isValid()) { 
      $locale = $form->get('language')->getData(); 
      $router = $this->get('router'); 

      // Create URL path to pass it to matcher 
      $urlParts = parse_url($referer); 
      $basePath = $request->getBaseUrl(); 
      $path = str_replace($basePath, '', $urlParts['path']); 

      // Match route and get it's arguments 
      $route = $router->match($path); 
      $routeAttrs = array_replace($route, array('_locale' => $locale)); 
      $routeName = $routeAttrs['_route']; 
      unset($routeAttrs['_route']); 

      // Set Locale 
      $this->get('session')->setLocale($locale); 

      return new RedirectResponse($router->generate($routeName, $routeAttrs)); 
     } 

     return new RedirectResponse($referer); 
    } 
} 

適用於任何有效的語言環境(你將它們作爲「語言」選項,同時創造你的形式),提供的PHP擴展國際啓用。如果不是,則需要用手動創建的區域名稱列表替換\Locale::getDisplayName($lang)

+0

請注意:引用者可能會被某些極客重寫,然後'$ router-> match()'會拋出一個異常,因爲沒有匹配。一個後備可能會很好:-) –

5

我還沒有做到這一點的形式,但只是在屏幕頂部的小旗子圖像。每個標誌都是指向當前頁面的鏈接,但URL中的雙字母語言代碼會被相應標誌的語言替換。我的佈局模板具有下面的代碼:

的replaceLanguageInUrl功能在我的枝條延伸類中定義:

public function getFunctions() 
{ 
    return array(
     'replaceLanguageInUrl' => new \Twig_Function_Method($this, 'replaceLanguageInUrl'), 
    ); 
}  

public function replaceLanguageInUrl($currentLanguage, $newLanguage, $url) 
{ 

    //EDIT BEGIN 
    if (strpos($url,$currentLanguage) == false) { 
     $url = getBaseUrl($url).'/'.$currentLanguage; 
    } 
    //EDIT END 
    return str_replace('/' . $currentLanguage . '/', '/' . $newLanguage . '/', $url); 
} 

當點擊一個標誌,同樣的頁面加載,但在新的語言。這也會在會話中自動設置新的語言。

2

我在本地做過,但比wdev的解決方案更簡單一些,我用一些圖片(標誌)作爲按鈕。單擊標誌時,將設置新的區域設置,並使用新語言刷新頁面(通過重定向)。您需要使用Symfony's translation system。下面是代碼:

控制器:

public function englishAction(Request $request) 
{ 
    $this->get('session')->setLocale('en_US'); 
    return $this->redirect($request->headers->get('referer')); 
} 

public function chineseAction(Request $request) 
{ 
    $this->get('session')->setLocale('zh_CN'); 
    return $this->redirect($request->headers->get('referer')); 
} 

public function frenchAction(Request $request) 
{ 
    $this->get('session')->setLocale('fr_FR'); 
    return $this->redirect($request->headers->get('referer')); 
} 

模板:

<ul class="nav pull-right"> 
    <li> 
      <a href="{{ path('english') }}"><img src="{{ asset('bundles/fkmywebsite/images/flag-en.png') }}" alt="English Language" height="30" width="18" /></a> 
    </li> 
    <li> 
      <a href="{{ path('chinese') }}"><img src="{{ asset('bundles/fkmywebsite/images/flag-cn.jpg') }}" alt="Chinese Language" height="30" width="18" /></a> 
    </li> 
    <li> 
     <a href="{{ path('french') }}"><img src="{{ asset('bundles/fkmywebsite/images/flag-fr.png') }}" alt="French Language" height="30" width="18" /></a> 
    </li> 
</ul> 

編輯:此解決方案可與Symfony2.0,爲Symfony2.1檢查this question

31

最簡單的方法我發現是直接在樹枝模板中做的。至少,它適用於2.2:

<ul class="lang-menu"> 
    <li><a href="{{ path(app.request.get('_route'), app.request.get('_route_params')|merge({'_locale': 'ca'})) }}">Català</a></li> 
    <li><a href="{{ path(app.request.get('_route'), app.request.get('_route_params')|merge({'_locale': 'en'})) }}">English</a></li> 
</ul> 
+0

偉大而輕量級的解決方案! – eav

+0

不爲我工作,在某些頁面中出現錯誤「在呈現模板期間拋出異常(」無法生成指定路由的URL「,因爲此路由不存在。」)「出現路徑不受影響網址 –

+0

它對我很好。問:你在正式文件(Symfony2書)中從哪裏學習? – mario