我创建了一个不打算翻译的应用程序,但现在我决定添加此功能。问题是我的所有路线都是这样的:
goodbye:
pattern: /goodbye
defaults: { _controller: AcmeBudgetTrackerBundle:Goodbye:goodbye }
我希望他们现在是这样的:
goodbye:
pattern: /goodbye/{_locale}
defaults: { _controller: AcmeBudgetTrackerBundle:Goodbye:goodbye, _locale: en }
requirements:
_locale: en|bg
我是否真的必须这样做,有没有办法做更全局或自动,或至少只添加一次请求,因为它们对所有网址都是一样的?非常感谢提前!
答案 0 :(得分:17)
使用JMS18nRoutingBundle(documentation)来达到此目的。没有自定义加载器,没有编码...
捆绑包能够使用语言环境为您的所有路由添加前缀,而不会更改除捆绑包的某些配置之外的任何内容。这是帮助您入门的最快(也是我推荐的)解决方案。
您甚至可以翻译不同语言区域的现有路线。
可以在this coderwall post中找到快速介绍。
答案 1 :(得分:13)
您可以在全局配置文件中以这种方式执行此操作
customsite:
resource: "@CustomSiteBundle/Resources/config/routing.yml"
prefix: /{_locale}
requirements:
_locale: fr|en
defaults: { _locale: fr}
反应相当缓慢,但有一些类似的问题。
很高兴知道您在导入资源时也可以删除{_locale}前缀。然后,您需要将{_locale}添加到每个特定路线。
通过这种方式,您无需重写要求和默认设置即可在包中找到没有语言环境的www.domain.com。
但是,您可以始终在全局路由配置中定义www.domain.com路由。
答案 2 :(得分:3)
配置symfony进行本地化:
向会话添加本地化(请注意约定是/ locale / action):
goodbye:
pattern: /{_locale}/goodbye
defaults: { _controller: AcmeBudgetTrackerBundle:Goodbye:goodbye, _locale: en }
requirements:
_locale: en|bg
也可以手动设置区域设置:
$this->get('session')->set('_locale', 'en_US');
应用/配置/ config.yml 强>
framework:
translator: { fallback: en }
在您的回复中:
use Symfony\Component\HttpFoundation\Response;
public function indexAction()
{
$translated = $this->get('translator')->trans('Symfony2 is great');
return new Response($translated);
}
配置本地化消息本地化文件:
messages.bg
<?xml version="1.0"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="file.ext">
<body>
<trans-unit id="1">
<source>Symfony2 is great</source>
<target>Symfony2 е супер</target>
</trans-unit>
<trans-unit id="2">
<source>symfony2.great</source>
<target>Symfony2 е супер</target>
</trans-unit>
</body>
</file>
</xliff>
messages.fr
<?xml version="1.0"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="file.ext">
<body>
<trans-unit id="1">
<source>Symfony2 is great</source>
<target>J'aime Symfony2</target>
</trans-unit>
<trans-unit id="2">
<source>symfony2.great</source>
<target>J'aime Symfony2</target>
</trans-unit>
</body>
</file>
</xliff>
有关该主题的更多信息:Official symfony documentation
答案 3 :(得分:3)
更好的解决方案而不是在所有路由或全局范围中放置需求是使用EventListener并将用户重定向到相同的路由,但是使用受支持的语言环境,例如:
<?php
namespace Selly\WebappLandingBundle\EventListener;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class LocaleInParamListener implements EventSubscriberInterface
{
/**
* @var Symfony\Component\Routing\RouterInterface
*/
private $router;
/**
* @var string
*/
private $defaultLocale;
/**
* @var array
*/
private $supportedLocales;
/**
* @var string
*/
private $localeRouteParam;
public function __construct(RouterInterface $router, $defaultLocale = 'en_US', array $supportedLocales = array('en_US'), $localeRouteParam = '_locale')
{
$this->router = $router;
$this->defaultLocale = $defaultLocale;
$this->supportedLocales = $supportedLocales;
$this->localeRouteParam = $localeRouteParam;
}
public function isLocaleSupported($locale) {
return in_array($locale, $this->supportedLocales);
}
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
$locale = $request->get($this->localeRouteParam);
if(null !== $locale) {
$routeName = $request->get('_route');
if(!$this->isLocaleSupported($locale)) {
$routeParams = $request->get('_route_params');
if (!$this->isLocaleSupported($this->defaultLocale))
throw \Exception("Default locale is not supported.");
$routeParams[$this->localeRouteParam] = $this->defaultLocale;
$url = $this->router->generate($routeName, $routeParams);
$event->setResponse(new RedirectResponse($url));
}
}
}
public static function getSubscribedEvents()
{
return array(
// must be registered before the default Locale listener
KernelEvents::REQUEST => array(array('onKernelRequest', 17)),
);
}
}
services.yml
services:
selly_webapp_landing.listeners.localeInParam_listener:
class: Selly\WebappLandingBundle\EventListener\LocaleInParamListener
arguments: [@router, "%kernel.default_locale%", "%locale_supported%"]
tags:
- { name: kernel.event_subscriber }
在parameters.yml
中,您可以指定支持的区域设置:
locale_supported: ['en_US', 'pl_PL']
答案 4 :(得分:1)
我认为你需要一个自定义加载器来扩展经典的配置加载器(Symfony \ Component \ Config \ Loader \ Loader)并操纵模式
http://symfony.com/doc/current/cookbook/routing/custom_route_loader.html
检查第一个例子,我还没有尝试过,但我很确定它会适合你的问题。
答案 5 :(得分:0)
您可以看到此解决方案:https://stackoverflow.com/a/37168304/6321297
如果要将路由中的{_local}
参数应用于所有路由,则必须在app / config路由文件中。
如果网址中没有{_local}
,此解决方案会使用事件侦听器重定向到好网址:
将yoursite.com/your/route
更改为yoursite.com/{_locale}/your/route
有或没有参数。