10

我创建了一个不打算翻译的应用程序,但现在我决定添加这个功能。问题是我所有的路线都是这样的:

goodbye:
    pattern: /goodbye
    defaults: { _controller: AcmeBudgetTrackerBundle:Goodbye:goodbye }

我希望他们现在是这样的:

goodbye:
    pattern: /goodbye/{_locale}
    defaults: { _controller: AcmeBudgetTrackerBundle:Goodbye:goodbye, _locale: en }
    requirements:
        _locale: en|bg

我真的必须这样做吗?有没有办法做更多的全局或自动操作,或者至少只添加一次要求,因为它们对于所有 url 都是相同的?非常感谢提前!

4

6 回答 6

18

为此目的使用JMS18nRoutingBundle文档)。没有自定义加载器,没有编码......

捆绑包能够为您的所有路由添加区域设置前缀,而无需更改捆绑包的某些配置之外的任何内容。这是帮助您入门的最快(也是我推荐的)解决方案。

您甚至可以为不同的语言环境翻译现有路线。

可以在此 coderwall 帖子中找到快速介绍。

于 2013-07-12T19:39:58.200 回答
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 路由。

于 2013-12-27T00:42:08.777 回答
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);
}

配置本地化消息本地化文件:

消息.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>

消息.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>

更多主题:官方 symfony 文档

于 2013-07-12T08:25:54.390 回答
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']
于 2014-05-28T08:51:07.630 回答
1

I think you need a custom loader extending the classic config loader (Symfony\Component\Config\Loader\Loader) and manipulate the pattern

http://symfony.com/doc/current/cookbook/routing/custom_route_loader.html

check the first example, i haven't tried it yet, but i'm quite sure it will fit your problem.

于 2013-07-12T08:22:02.047 回答
0

你可以看到这个解决方案:https ://stackoverflow.com/a/37168304/6321297

{_local}如果要将其应用于所有路由,则路由中的参数必须在 app/config 路由文件中。

如果 url 中没有{_local},此解决方案使用事件侦听器重定向到好的 url:更改yoursite.com/your/routeyoursite.com/{_locale}/your/route

它可以在有或没有参数的情况下工作。

于 2016-05-11T17:12:50.317 回答