2017-09-03 10 views
2

私はSymfony 3を使用しています。 私のウェブサイトはフランス語と英語の2言語であり、人々は選択したフォームで切り替えることができます。 デフォルトの言語はフランス語です。 メインURLは example.com/fr(フランス語版)、example.com/en(英語版)symfony 3、ブラウザの言語を検出

ユーザーがウェブサイトにアクセスしてブラウザの言語を検出し、自動的に正しい言語。 Exemple、ブラウザはフランス語であれば、彼はフランス語版にリダイレクトされます。彼は英語版にリダイレクトされexample.com/frエルス :example.com/en

が適切にそれを行うための方法があります?あなたは、例えば、あなたはsymfonyのイベントシステムに自分が使い慣れた確認する必要がありJMSI18nRoutingBundle のような他のバンドルに依存したくない場合は

はあなたの助け

+0

'JMSI18nRoutingBundle'を試してください。また、 'Accept-Language'リクエストヘッダーを手動で分析することもできます。 –

答えて

3

いただき、ありがとうございますHttpKernelを読んでください。

あなたの場合、kernel.requestイベントにフックしたい場合。

一般的な目的:リクエストに情報を追加するには、システムの一部を初期化するか、可能であればレスポンスを返す(たとえば、アクセスを拒否するセキュリティー層)。

カスタムEventListenerでは、そのイベントをリスンすることで、ルータで使用されているRequestオブジェクトに情報を追加できます。

class LanguageListener implements EventSubscriberInterface 
{ 
    private $supportedLanguages; 

    public function __construct(array $supportedLanguages) 
    { 
     if (empty($supportedLanguages)) { 
      throw new \InvalidArgumentException('At least one supported language must be given.'); 
     } 

     $this->supportedLanguages = $supportedLanguages; 
    } 

    public static function getSubscribedEvents() 
    { 
     return [ 
      KernelEvents::REQUEST => ['redirectToLocalizedHomepage', 100], 
     ]; 
    } 

    public function redirectToLocalizedHomepage(GetResponseEvent $event) 
    { 
     // Do not modify sub-requests 
     if (KernelInterface::MASTER_REQUEST !== $event->getRequestType()) { 
      return; 
     } 
     // Assume all routes except the frontpage use the _locale parameter 
     if ($event->getRequest()->getPathInfo() !== '/') { 
      return; 
     } 

     $language = $this->supportedLanguages[0]; 
     if (null !== $acceptLanguage = $event->getRequest()->headers->get('Accept-Language')) { 
      $negotiator = new LanguageNegotiator(); 
      $best  = $negotiator->getBest(
       $event->getRequest()->headers->get('Accept-Language'), 
       $this->supportedLanguages 
      ); 

      if (null !== $best) { 
       $language = $best->getType(); 
      } 
     } 

     $response = new RedirectResponse('/' . $language); 
     $event->setResponse($response); 
    } 
} 

このリスナーは、要求のAccept-Languageヘッダをチェックして、最高のロケールを決定するために交渉の\ LanguageNegotiatorを使用します。それはこのような何かを見ることができます。 use文を追加しなかったので注意してください。しかし、かなり明白でなければなりません。

さらに高度なバージョンの場合は、JMSI18nRoutingBundleからLocaleChoosingListenerのソースを読むことができます。

これを行うことは、通常、フロントページでのみ必要となります。そのため、私が掲載した例とJMSBundleからの例は、他のすべてのパスを除外しています。マニュアルに記載されたもののためにあなただけの特別なパラメータ_localeを使用することができます。

https://symfony.com/doc/current/translation/locale.html#the-locale-and-the-url

symfonyのドキュメントもロケールを読んで、リスナーを使用して、セッション中に、それは粘着性にする方法の例が含まれていますhttps://symfony.com/doc/current/session/locale_sticky_session.html この例では、services.ymlにListenerを登録する方法も示しています。

関連する問題