如果你不希望依賴其他包一樣JMSI18nRoutingBundle 你已經讓自己熟悉的Symfony的事件系統,例如通過閱讀HttpKernel。
爲了您的情況,您希望掛入kernel.request
事件。
典型用途:詳細信息添加到請求中,初始化該系統的部分,或返回一個響應,如果可能的(例如,拒絕訪問的安全層)。
在您的自定義EventListener中,您可以偵聽該事件添加信息到您的路由器中使用的請求對象。它可能是這個樣子:
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以確定最佳的語言環境。要小心,因爲我沒有添加使用語句,但它們應該相當明顯。
對於更高級的版本,您可以從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。
試試'JMSI18nRoutingBundle'。你也可以手動分析'Accept-Language'請求頭。 –