Symfony2 locale languages whole page event listener

前端 未结 2 1038
时光取名叫无心
时光取名叫无心 2020-12-10 20:29

I need to create a system like the facebook lang system when a user clicks on language to example france(\'fr\') the page will reload and all the content in messages.fr.yml

2条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-10 21:03

    The listener works and helped me a lot. I reused the script to set locale (with subtag region) and language (locale language code) in session

         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)),
        );
        }
    
        }
        ?>
    

    A form in a controller if you send post parameters:

        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())
            );
        }
    

    The example twig form:

        
    {{ form_widget(_localeForm)}}

    {{ form_rest(_localeForm) }}

    Send locale in url, better if get array of locales from configuration with twig functions:

        {% for locale in ('fer_cave.backend._locale'|caveParam)|keys %}
        
  • {#{{ locale }}#} {% set route = app.request.get('_route') %} {% set route_params = app.request.get('_route_params') %} {{ locale }} {% endfor %} {# Locale in session: {{app.session.get('_locale')}}
    Language in session: {{app.session.get('language')}}
    Locale as get param: {{app.request.get('_locale')}}
    Locale as post {{app.request.request.get('_locale')}} #}
  • Add serviceContainer to the listener if you want retrieve locales fromyour bundle configuration:

        
            %locale%
            
            
        
    

    Why not, the sample configuration array in 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')            
    

    Cleaner in config parameters of the bundle:

    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 
    

    Now I can set Session _locale and language with get, post or browser configuration.

    Hope to be clear with my english and sorry because editing text continously.

提交回复
热议问题