翻訳を目的としないアプリケーションを作成しましたが、この機能を追加することにしました。問題は、すべてのルートが次のようになっていることです。
goodbye:
pattern: /goodbye
defaults: { _controller: AcmeBudgetTrackerBundle:Goodbye:goodbye }
そして私はそれらを今このようにしたいと思います:
goodbye:
pattern: /goodbye/{_locale}
defaults: { _controller: AcmeBudgetTrackerBundle:Goodbye:goodbye, _locale: en }
requirements:
_locale: en|bg
私は本当にこれを行う必要があり、よりグローバルまたは自動で行う方法はありますか、または少なくとも1回だけ要件を追加する方法はありますか?それらはすべてのURLで同じであるためですか?よろしくお願いします!
この目的には JMS18nRoutingBundle ( ドキュメント )を使用します。カスタムローダーもコーディングもありません...
バンドルは、バンドルの一部の構成を除いて何も変更せずに、すべてのルートにロケールのプレフィックスを付けることができます。それはあなたが始めるための最も速い(そして私の推奨する)解決策です。
さまざまなロケールの既存のルートを変換することもできます。
簡単な紹介は このコーダーウォールの投稿 にあります。
グローバル構成ファイルで、このように行うことができます
customsite:
resource: "@CustomSiteBundle/Resources/config/routing.yml"
prefix: /{_locale}
requirements:
_locale: fr|en
defaults: { _locale: fr}
反応はかなり遅いですが、同様の問題がいくつかありました。
リソースをインポートするときに{_locale}プレフィックスを削除することもできます。次に、すべての特定のルートに{_locale}を追加する必要があります。
このようにして、要件とデフォルトを書き直すことなく、バンドル内からロケールなしでwww.domain.comをキャッチできます。
ただし、グローバルルーティング構成で常にwww.domain.comルートを定義できます。
すべてのルートまたはグローバルスコープに要件を設定する代わりに、より良い解決策は、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']
ローカリゼーションのために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');
app/config/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>
トピックの詳細: 公式のsymfonyドキュメント
クラシックな設定ローダー(Symfony\Component\Config\Loader\Loader)を拡張してパターンを操作するカスタムローダーが必要だと思います
http://symfony.com/doc/current/cookbook/routing/custom_route_loader.html
最初の例を確認してください。まだ試していませんが、問題に合うと確信しています。
あなたはこの解決策を見ることができます: https://stackoverflow.com/a/37168304/6321297
ルートの{_local}
パラメータをすべてのルートに適用する場合は、app/configルーティングファイルに含める必要があります。
このソリューションは、URLに{_local}
がない場合、イベントリスナーを使用して適切なURLにリダイレクトします。yoursite.com/your/route
をyoursite.com/{_locale}/your/route
に変更します。
パラメータの有無にかかわらず機能します。