2013-02-15 135 views
3

我需要創建一個系統,比如當用戶點擊語言來實現例如法國('fr')頁面將重新加載並且messages.fr.yml中的所有內容被顯示...Symfony2語言環境語言整頁事件監聽器

我試圖讓路線像/language/{localExtension},但當我設置Locale那裏,然後重定向它沒有工作......我不知道我假設它只是爲某些頁面不全球?因爲當我在我的控制器頂部它的工作原理...

設置setLocale('fr')我發現當使用www.example.com/contact/en/contact/fr

但我想從以前選擇的語言顯示/contact和內容的文章。或默認成「en」就像現在,當用戶沒有改變它...

我google搜索了一整天,我覺得應該用...的服務=>監聽器來完成,並...上kernel.request?或類似的東西。

這裏是intresting鏈接Symfony2 wrong locale detection?我認爲這就是我需要的?要麼?我試圖設置的服務,創造監聽器,但一些錯誤出現,我甚至不知道這是怎樣的方式來創建它:由於某種原因,你需要使用一個監聽器/

回答

6

是:

<?php 

namespace Your\Bundle\Listener; 

use Symfony\Component\HttpKernel\Event\GetResponseEvent; 
use Symfony\Component\HttpKernel\KernelEvents; 
use Symfony\Component\EventDispatcher\EventSubscriberInterface; 

class LocaleListener implements EventSubscriberInterface 
{ 
    private $defaultLocale; 

    public function __construct($defaultLocale = 'en') 
    { 
    $this->defaultLocale = $defaultLocale; 
    } 

    public function onKernelRequest(GetResponseEvent $event) 
    { 
    $request = $event->getRequest(); 
    if (!$request->hasPreviousSession()) { 
     return; 
    } 

    if ($locale = $request->attributes->get('_locale')) { 
     $request->getSession()->set('_locale', $locale); 
    } else { 
     $request->setLocale($request->getSession()->get('_locale', $this->defaultLocale)); 
    } 
    } 

    static public function getSubscribedEvents() 
    { 
    return array(
     // must be registered before the default Locale listener 
     KernelEvents::REQUEST => array(array('onKernelRequest', 17)), 
); 
    } 
} 
?> 

註冊在service.xml中監聽:

<service id="my.listener" class="Your\Bundle\Listener\LocaleListener"> 
    <argument>%locale%</argument> 
    <tag name="kernel.event_subscriber"/> 
</service> 

一個例子如何實現你的樹枝模板語言切換:

{% for locale in ['en', 'fr','zh'] %} 
    <li> 
     <a href="{{ path(app.request.get('_route'), app.request.get('_route_params')|merge({'_locale' : locale})) }}"> 
     {% if locale == 'en' %} 
     <img title="English" src="{{ asset('bundles/fkmywebsite/images/UnitedStates.png') }}" alt="English" height="30" width="30"/> 
     {% elseif locale == 'fr' %} 
     <img title="Français" src="{{ asset('bundles/fkmywebsite/images/France.png') }}" alt="Français" height="30" width="30"/> 
     {% endif %} 
     </div> 
    </li> 
{% endfor %} 
+0

好人,真好。我現在無法嘗試,因爲我使用了語言環境包,因爲我無法找到答案,而且在這裏沒有人幫助,但thx很多!似乎是功能性的。 – EnchanterIO 2013-02-17 10:38:53

+1

locale_listener: 類:ACME \ DemoBundle \監聽\ LocaleListener 參數:[ 「%區域設置%」] 標籤: - {名稱: 'kernel.event_subscriber'} YML配置參考:) – 2013-03-14 09:26:51

0

聽者的工作和幫助了我很多。我重複使用的腳本會話設置區域設置(與子標籤區)和語言(區域語言代碼)

 <?php 
    namespace Fer\CaveBundle\EventListener; 
    use Symfony\Component\HttpKernel\Event\GetResponseEvent; 
    use Symfony\Component\HttpKernel\KernelEvents; 
    use Symfony\Component\EventDispatcher\EventSubscriberInterface; 
    use Symfony\Component\HttpFoundation\Session\Session; 
    use Symfony\Component\DependencyInjection\ContainerInterface; 

    class LocaleListener implements EventSubscriberInterface 
    { 
     private $defaultLocale; 
     private $locales; 

    public function __construct($defaultLocale='es', ContainerInterface $container) 
    { 
     //values from configuration of my bundle 
     $backend = $container->getParameter('cave.backend'); 
     $this->locales = $backend['_locale']; 

    // $this->locales = array('es'=>'es_ES' 
    //       'en'=>'en_GB,en_US', 
    //       'fr'=>'fr_FR,fr_BG' 
    //      ); 
     //default must exists in _locales array. locale_lookup Default: es_ES 
     $this->defaultLocale = locale_lookup(array_keys($this->locales), 
              $defaultLocale, 
              false, 
              current(explode(',',implode(',',array_values($this->locales))))); 


    } 

    public function onKernelRequest(GetResponseEvent $event) 
    { 
     $request = $event->getRequest(); 
     $session = $request->getSession(); 

     // Locale Get parameters 
     if($locale = $request->query->get('_locale')) 
     { 
      $this->setLocale($request, $session, $locale); 
      return; 
     } 

     // Locale Post parameters with custom form name 
     if($locale = $request->request->get('_localeForm')) 
     { 
     $this->setLocale($request, $session, $locale['_locale']); 
     return; 
     } 

     // Locale session parameters 
     if($locale = $session->get('_locale')) 
     { 
      $this->setLocale($request, $session, $locale); 
      return; 
     }  

     //Locale in browser 
     if($locale = $request->getPreferredLanguage()){ 
      $this->setLocale($request, $session, $locale); 
      return; 
     }  

     $this->setLocale($request, $session, $this->defaultLocale); 
     return; 
    } 

    public function setLocale($request,$session,$locale) 
    { 
      //search language and lookup, default first locale in language 
      if(in_array(current(locale_parse($locale)),array_keys($this->locales))){ 
       $locale = locale_lookup(explode(',',$this->locales[current(locale_parse($locale))]), 
            $locale, 
            false, 
            current(explode(',',$this->locales[current(locale_parse($locale))]))); 
      }else{ 
       $locale = $this->defaultLocale; 
      } 

      //set session parameter 
      if($locale!==$session->get('_locale')){ 
       $session->set('_locale',$locale); 
       $session->set('language', current(locale_parse($locale)));//language code 
      } 
      //Set the default PHP locale.(for translations) 
      $request->setLocale($locale); 
      //set post parameter 
      $request->request->set('_locale',$locale); 
      //set get parameter 
      $request->query->set('_locale',$locale); 


      return; 
    } 

    static public function getSubscribedEvents() 
    { 
    return array(
     // must be registered before the default Locale listener 
     KernelEvents::REQUEST => array(array('onKernelRequest', 17)), 
    ); 
    } 

    } 
    ?> 

在控制器的形式,如果您發送POST參數:

public function indexAction() 
    { 
     $form = $this->get('form.factory')->createNamedBuilder('_localeForm') 
      ->add('_locale', 'choice', array(
       'choices' => array('en' => 'english', 'es' => 'Español'),//etc 
       'required' => true, 
      ))->getForm(); 

      return $this->render(
      'myProject:myBundle:index.html.twig', 
      array('_localeForm' => $form->createView()) 
     ); 
    } 

的例子樹枝形式:

<form action="" method="post" {{ form_enctype(_localeForm) }}> 
    {{ form_widget(_localeForm)}} <br><br> 
    <input type="submit" value="Enviar" /> 
    {{ form_rest(_localeForm) }} 
    </form> 

發送的語言環境中的網址,更好,如果從配置獲取語言環境的數組,樹枝功能:

{% for locale in ('fer_cave.backend._locale'|caveParam)|keys %} 
    <li {% if locale == app.session.get('language') %}class="active" style="color: red"{% endif %}> 
    {#<a href="{{path(app.request.get('_route'), {'_locale': locale}) }}">{{ locale }}</a>#} 
    {% set route = app.request.get('_route') %} 
    {% set route_params = app.request.get('_route_params') %} 
    <a href="{{ path(route, route_params | merge({ '_locale': locale })) }}">{{ locale }}</a> 
    {% endfor %} 
    {# 
    Locale in session: {{app.session.get('_locale')}}<br> 
    Language in session: {{app.session.get('language')}}<br> 
    Locale as get param: {{app.request.get('_locale')}}<br> 
    Locale as post {{app.request.request.get('_locale')}} 
    #} 

添加的ServiceContainer給聽衆,如果你想獲取本地化fromyour束配置:

<service id="cave.listener" class="Fer\CaveBundle\EventListener\LocaleListener"> 
     <argument>%locale%</argument> 
     <argument type="service" id="service_container" /> 
     <tag name="kernel.event_subscriber"/> 
    </service> 

不爲什麼,在myProject的/ myBUndle/DependencyInjection樣本配置陣列

  //-------------------ejemplo de backend-------------------// 
    ->arrayNode('backend') 
     ->addDefaultsIfNotSet() 
     ->children() 
      ->arrayNode('_locale') 
       ->addDefaultsIfNotSet() 
       ->children() 
        ->scalarNode('es')->defaultValue('es_ES')->end()//language=>region 
        ->scalarNode('en')->defaultValue('en_GB,en_US')->end()// 
        ->scalarNode('fr')->defaultValue('fr_FR,fr_BG')->end()//     
       ->end() 
      ->end()//end arrayNode('_locale') 
      ->scalarNode('encoding')->defaultValue('UTF-8')->end() 
     ->end() 
    ->end()//end arrayNode('backend')    

清潔的配置參數捆綁:

fer_cave.backend: 
    _locale: {es: [es_ES],en: [en_GB,en_US],fr: [fr_FR,fr_BG]} 
    encoding: UTF-8 
cave.frontend: 
    _locale: {es: es_ES}  
    encoding: UTF-8 

N我可以通過獲取,發佈或瀏覽器配置來設置Session _locale和語言。

希望能夠清楚我的英語和對不起,因爲編輯文本不斷。

+0

UPH .... thx爲您的回覆...它太晚了,我現在沒有時間去嘗試它...我可能會遇到這個問題,稍後我會告訴你,如果有東西:)但thx爲你的時間;)不要擔心英語:D一切都夠乾淨。 – EnchanterIO 2013-05-30 21:27:01