gpt4 book ai didi

symfony - JMSI18nRoutingBundle 可以使用 HTTP Accept-Language 数组吗?

转载 作者:行者123 更新时间:2023-12-04 15:10:58 26 4
gpt4 key购买 nike

我正在尝试做一个国际化的网站,我翻译的每种语言都有一个 URL 前缀(例如 /fr/my/page/it/my/page )。

我尝试了 JMSI18nRoutingBundle,它几乎不需要额外的配置就可以很好地工作。但我真的很想自动确定用户的首选语言。
用户喜欢的语言被传输到Accept-Language HTTP header ,我想选择我有翻译的第一种语言。

这是我的 JMSI18nRouting 配置:

jms_i18n_routing:
default_locale: en
locales: [fr, en]
strategy: prefix_except_default

我想要这种行为:
http://mywebsite.com/my/page进行自动语言检测,然后重定向到 /xx/... (其中 xx 是用户最喜欢的语言)因为 URL 中未指定语言 - 目前默认语言是 EN。
http://mywebsite.com/XX/my/page以 XX 语言显示页面 - 目前,工作正常。

有什么想法吗?配置好吗?

哦,而且,如果有人有解决方案在纯 Symfony 中做同样的事情(没有 JMSI18nRoutingBundle),我的耳朵很开放。

编辑/找到了一种使用 JMSI18nRoutingBundle 进行智能重定向的方法,以尊重用户最喜欢的语言或让用户强制显示一种语言。见我的answer .

最佳答案

最后,我回答我的问题。

我开发了一个小“补丁”使用 JMSI18nRoutingBundle 并检测用户的首选语言,并让用户强制使用一种语言。

创建监听器YourBundle/EventListener/LocaleListener.php
如果用户的首选区域设置与 Symfony 或 JMSI18nRoutingBundle 定义的区域设置不同,此监听器将更改 URL。通过这种方式,您有两个 URL 用于两种不同语言的两种不同内容:它是 SEO 友好的。

您还可以创建一个由链接到 ?setlang=xx 的链接组成的语言选择器。在哪里 xx是用户想要显示的语言。监听器将检测到 setlang查询并将强制显示 xx lang,包括在下一个请求中。

注意 $this->translatable = [...大批。它可以让您定义网站的哪些部分可以翻译/可翻译。粒度可以从供应商定义到操作方法。
您还可以创建一个配置节点来定义您的可翻译供应商/捆绑包/ Controller ,出于性能考虑,我没有这样做。

<?php

namespace YourVendor\YourBundle\EventListener;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class LocaleListener implements EventSubscriberInterface
{
private $defaultLocale;
private $acceptedLocales;
private $translatable;

public function __construct($router, $defaultLocale, $acceptedLocales)
{
$this->router = $router;
$this->defaultLocale = $defaultLocale;
$this->acceptedLocales = $acceptedLocales;

$this->translatable = [
'Vendor1',
'Vendor2\Bundle1',
'Vendor2\Bundle2\Controller1',
'Vendor2\Bundle2\Controller2::myPageAction',
];
}

public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
$route = $request->get('_route');

if(!empty($newLocale = $request->query->get('setlang'))) {
if(in_array($newLocale, $this->acceptedLocales)) {
$cookie = new Cookie('force_lang', $newLocale, time() + 3600 * 24 * 7);

$url = $this->router->generate($route, ['_locale' => $newLocale] + $request->attributes->get('_route_params'));

$response = new RedirectResponse($url);
$response->headers->setCookie($cookie);
$event->setResponse($response);
}
} else if($this->translatable($request->attributes->get('_controller'))) {
$preferred = empty($force = $request->cookies->get('force_lang')) ? $request->getPreferredLanguage($this->acceptedLocales) : $force;

if($preferred && $request->attributes->get('_locale') != $preferred) {
$url = $this->router->generate($route, ['_locale' => $preferred] + $request->attributes->get('_route_params'));
$event->setResponse(new RedirectResponse($url));
}
}
}

private function translatable($str)
{
foreach($this->translatable as $t) {
if(strpos($str, $t) !== false) return true;
}

return false;
}

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

在 HTTP 内核上绑定(bind)您的监听器。

编辑您的 services.yml文件。
services:
app.event_listener.locale_listener:
class: YourVendor\YourBundle\EventListener\LocaleListener
arguments: ["@router", "%kernel.default_locale%", "%jms_i18n_routing.locales%"]
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
JMSI18nRoutingBundle的配置

你没有什么可以改变的。
例子:
# JMS i18n Routing Configuration
jms_i18n_routing:
default_locale: "%locale%"
locales: [fr, en]
strategy: prefix_except_default

关于symfony - JMSI18nRoutingBundle 可以使用 HTTP Accept-Language 数组吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27537513/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com