3

ユーザーが言語をクリックしてfrance('fr')の例を示すと、facebook langシステムのようなシステムを作成する必要があります。ページがリロードされ、messages.fr.ymlのすべてのコンテンツが表示されます...

ルートを次のように作成しようとしまし/language/{localExtension}たが、そこにLocaleを設定してリダイレクトすると、機能しませんでした...グローバルではない特定のページだけを想定しているのかわかりません。コントローラーの上部に設定setLocale('fr')すると機能するからです...

を使用しているときにいくつかの記事を見つけましたwww.example.com/contact/en/contact/frなど

しかし、私/contactは以前に選択した言語からコンテンツを表示したいと思っています。または、ユーザーが変更しなかったときのように、デフォルトの「en」...

私は一日中グーグルをしていました、そして私はそれが... service=>リスナーと...kernel.requestで行われるべきだと思いますか?またはそのようなもの。

ここに興味深いリンクSymfony2の間違ったロケール検出がありますか?私はそれが私が必要なものだと思いますか?また?サービスを設定してリスナーを作成しようとしましたが、いくつかのエラーが表示され、これが作成方法であるかどうかさえわかりません:/

4

2 に答える 2

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 %}
于 2013-02-17T09:42:49.923 に答える
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)),
    );
    }

    }
    ?>

投稿パラメーターを送信する場合のコントローラーのフォーム:

    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>

twig 関数を使用して構成からロケールの配列を取得する場合は、URL でロケールを送信します。

    {% 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 をリスナーに追加します。

    <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 

これで、get、post、または browser 構成で Session _locale と language を設定できるようになりました。

テキストを継続的に編集しているため、私の英語が明確になることを願っています。

于 2013-05-30T17:27:14.180 に答える