Symfony2 语言环境整页事件监听器
Posted
技术标签:
【中文标题】Symfony2 语言环境整页事件监听器【英文标题】:Symfony2 locale languages whole page event listener 【发布时间】:2013-01-31 23:23:39 【问题描述】:当用户点击语言时,我需要创建一个类似于 facebook lang 系统的系统,例如 france('fr') 页面将重新加载,messages.fr.yml 中的所有内容都将显示...
我尝试创建像/language/localExtension
这样的路由,但是当我在那里设置Locale 然后重定向它不起作用...我不知道我假设它只是针对某个页面而不是全局的?因为当我在控制器顶部设置setLocale('fr')
时,它可以工作......
我在使用www.example.com/contact/en
、/contact/fr
等时发现了一些文章
但我想要/contact
和以前选择的语言显示的内容。或者当用户没有更改它时,就像现在一样默认'en'......
我整天都在谷歌搜索,我认为应该通过...服务 => 侦听器和...在 kernel.request 上完成?或类似的东西。
这里是有趣的链接Symfony2 wrong locale detection? 我想这就是我需要的吗?要么?我尝试设置服务并创建侦听器,但出现了一些错误,我什至不知道这是否是创建它的方式:/
【问题讨论】:
【参考方案1】:是的,出于某种原因,您需要使用监听器:
<?php
namespace Your\Bundle\Listener;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class LocaleListener implements EventSubscriberInterface
private $defaultLocale;
public function __construct($defaultLocale = 'en')
$this->defaultLocale = $defaultLocale;
public function onKernelRequest(GetResponseEvent $event)
$request = $event->getRequest();
if (!$request->hasPreviousSession())
return;
if ($locale = $request->attributes->get('_locale'))
$request->getSession()->set('_locale', $locale);
else
$request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));
static public function getSubscribedEvents()
return array(
// must be registered before the default Locale listener
KernelEvents::REQUEST => array(array('onKernelRequest', 17)),
);
?>
在你的 service.xml 中注册你的监听器:
<service id="my.listener" class="Your\Bundle\Listener\LocaleListener">
<argument>%locale%</argument>
<tag name="kernel.event_subscriber"/>
</service>
一个如何在你的 twig 模板中实现语言切换器的例子:
% for locale in ['en', 'fr','zh'] %
<li>
<a href=" path(app.request.get('_route'), app.request.get('_route_params')|merge('_locale' : locale)) ">
% if locale == 'en' %
<img title="English" src=" asset('bundles/fkmywebsite/images/UnitedStates.png') " />
% elseif locale == 'fr' %
<img title="Français" src=" asset('bundles/fkmywebsite/images/France.png') " />
% endif %
</div>
</li>
% endfor %
【讨论】:
好人,真的很好。我现在无法尝试,因为我使用了语言环境包,因为我找不到答案,而且这里没有人提供帮助,但非常感谢!似乎可以正常工作。 locale_listener: class: Acme\DemoBundle\Listener\LocaleListener arguments: ["%locale%"] tags: - name: 'kernel.event_subscriber' Yml 配置参考 :)【参考方案2】:听众工作并帮助了我很多。我重用脚本在会话中设置区域设置(带有子标签区域)和语言(区域设置语言代码)
<?php
namespace Fer\CaveBundle\EventListener;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\DependencyInjection\ContainerInterface;
class LocaleListener implements EventSubscriberInterface
private $defaultLocale;
private $locales;
public function __construct($defaultLocale='es', ContainerInterface $container)
//values from configuration of my bundle
$backend = $container->getParameter('cave.backend');
$this->locales = $backend['_locale'];
// $this->locales = array( 'es'=>'es_ES'
// 'en'=>'en_GB,en_US',
// 'fr'=>'fr_FR,fr_BG'
// );
//default must exists in _locales array. locale_lookup Default: es_ES
$this->defaultLocale = locale_lookup(array_keys($this->locales),
$defaultLocale,
false,
current(explode(',',implode(',',array_values($this->locales)))));
public function onKernelRequest(GetResponseEvent $event)
$request = $event->getRequest();
$session = $request->getSession();
// Locale Get parameters
if($locale = $request->query->get('_locale'))
$this->setLocale($request, $session, $locale);
return;
// Locale Post parameters with custom form name
if($locale = $request->request->get('_localeForm'))
$this->setLocale($request, $session, $locale['_locale']);
return;
// Locale session parameters
if($locale = $session->get('_locale'))
$this->setLocale($request, $session, $locale);
return;
//Locale in browser
if($locale = $request->getPreferredLanguage())
$this->setLocale($request, $session, $locale);
return;
$this->setLocale($request, $session, $this->defaultLocale);
return;
public function setLocale($request,$session,$locale)
//search language and lookup, default first locale in language
if(in_array(current(locale_parse($locale)),array_keys($this->locales)))
$locale = locale_lookup(explode(',',$this->locales[current(locale_parse($locale))]),
$locale,
false,
current(explode(',',$this->locales[current(locale_parse($locale))])));
else
$locale = $this->defaultLocale;
//set session parameter
if($locale!==$session->get('_locale'))
$session->set('_locale',$locale);
$session->set('language', current(locale_parse($locale)));//language code
//Set the default PHP locale.(for translations)
$request->setLocale($locale);
//set post parameter
$request->request->set('_locale',$locale);
//set get parameter
$request->query->set('_locale',$locale);
return;
static public function getSubscribedEvents()
return array(
// must be registered before the default Locale listener
KernelEvents::REQUEST => array(array('onKernelRequest', 17)),
);
?>
如果您发送 post 参数,则控制器中的表单:
public function indexAction()
$form = $this->get('form.factory')->createNamedBuilder('_localeForm')
->add('_locale', 'choice', array(
'choices' => array('en' => 'english', 'es' => 'Español'),//etc
'required' => true,
))->getForm();
return $this->render(
'myProject:myBundle:index.html.twig',
array('_localeForm' => $form->createView())
);
示例树枝形式:
<form action="" method="post" form_enctype(_localeForm) >
form_widget(_localeForm) <br><br>
<input type="submit" value="Enviar" />
form_rest(_localeForm)
</form>
在 url 中发送语言环境,最好使用 twig 函数从配置中获取语言环境数组:
% for locale in ('fer_cave.backend._locale'|caveParam)|keys %
<li % if locale == app.session.get('language') %class="active" style="color: red"% endif %>
#<a href="path(app.request.get('_route'), '_locale': locale) "> locale </a>#
% set route = app.request.get('_route') %
% set route_params = app.request.get('_route_params') %
<a href=" path(route, route_params | merge( '_locale': locale )) "> locale </a>
% endfor %
#
Locale in session: app.session.get('_locale')<br>
Language in session: app.session.get('language')<br>
Locale as get param: app.request.get('_locale')<br>
Locale as post app.request.request.get('_locale')
#
如果您想从捆绑配置中检索语言环境,请将 serviceContainer 添加到侦听器:
<service id="cave.listener" class="Fer\CaveBundle\EventListener\LocaleListener">
<argument>%locale%</argument>
<argument type="service" id="service_container" />
<tag name="kernel.event_subscriber"/>
</service>
为什么不呢,myProject/myBUndle/DependencyInjection 中的示例配置数组
//-------------------ejemplo de backend-------------------//
->arrayNode('backend')
->addDefaultsIfNotSet()
->children()
->arrayNode('_locale')
->addDefaultsIfNotSet()
->children()
->scalarNode('es')->defaultValue('es_ES')->end()//language=>region
->scalarNode('en')->defaultValue('en_GB,en_US')->end()//
->scalarNode('fr')->defaultValue('fr_FR,fr_BG')->end()//
->end()
->end()//end arrayNode('_locale')
->scalarNode('encoding')->defaultValue('UTF-8')->end()
->end()
->end()//end arrayNode('backend')
bundle 配置参数中的清理器:
fer_cave.backend:
_locale: es: [es_ES],en: [en_GB,en_US],fr: [fr_FR,fr_BG]
encoding: UTF-8
cave.frontend:
_locale: es: es_ES
encoding: UTF-8
现在我可以使用 get、post 或浏览器配置来设置 Session _locale 和语言。
希望我的英语清楚,抱歉,因为不断编辑文本。
【讨论】:
uph....谢谢您的回复...太晚了,我现在没有时间尝试...我以后可能会遇到这个问题,如果有什么我会告诉你:) 但是谢谢你的时间 ;) 不要担心英语 :D 一切都足够干净。以上是关于Symfony2 语言环境整页事件监听器的主要内容,如果未能解决你的问题,请参考以下文章
刘志梅2017710101152.《面向对象程序设计(java)》第十三周学习总结
如何避免 Symfony 和 locale 路由的重复内容?