我想集成一個簡單的HTML表單,允許用戶更改Symfony2 Web應用程序的語言(即從頁面en/faq轉到fr/faq)。如何以適當的方式做到這一點?Symfony2語言選擇器
我已經發現了與Symfony的做的一個很好的方式,但不與Symfony2的:http://symfony.com/blog/play-with-the-user-language
我想集成一個簡單的HTML表單,允許用戶更改Symfony2 Web應用程序的語言(即從頁面en/faq轉到fr/faq)。如何以適當的方式做到這一點?Symfony2語言選擇器
我已經發現了與Symfony的做的一個很好的方式,但不與Symfony2的:http://symfony.com/blog/play-with-the-user-language
在你的路由定義使用_locale
參數自動設置用戶區域。
見http://symfony.com/doc/current/book/translation.html#the-locale-and-the-url
你需要調用$this->get('session')->setLocale($locale)
控制器內(由Symfony的2.1 '請求' 代替 '會話')。
我創建了一個表格,而我通過語言的數組:
<?php
class LanguageType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$langs = $options['languages'];
$langs = array_combine($langs, $langs);
foreach ($langs as &$lang) {
$lang = \Locale::getDisplayName($lang);
}
$builder->add('language', 'choice', array(
'choices' => $langs,
'required' => false,
));
}
public function getDefaultOptions(array $options)
{
return array(
'languages' => array('fr_FR', 'en_GB'),
'csrf_protection' => false,
);
}
public function getName()
{
return 'my_language';
}
}
我提交此表到一個單獨的動作在控制器中,我設定的區域,並返回一個重定向最後一頁:
<?php
class LanguageController extends Controller
{
public function switchLanguageAction()
{
$form = $this->get('form.factory')->create(
new LanguageType(),
array('language' => $this->get('session')->getLocale()),
array('languages' => $this->container->getParameter('roger.admin.languages', null))
);
$request = $this->get('request');
$form->bindRequest($request);
$referer = $request->headers->get('referer');
if ($form->isValid()) {
$locale = $form->get('language')->getData();
$router = $this->get('router');
// Create URL path to pass it to matcher
$urlParts = parse_url($referer);
$basePath = $request->getBaseUrl();
$path = str_replace($basePath, '', $urlParts['path']);
// Match route and get it's arguments
$route = $router->match($path);
$routeAttrs = array_replace($route, array('_locale' => $locale));
$routeName = $routeAttrs['_route'];
unset($routeAttrs['_route']);
// Set Locale
$this->get('session')->setLocale($locale);
return new RedirectResponse($router->generate($routeName, $routeAttrs));
}
return new RedirectResponse($referer);
}
}
適用於任何有效的語言環境(你將它們作爲「語言」選項,同時創造你的形式),提供的PHP擴展國際啓用。如果不是,則需要用手動創建的區域名稱列表替換\Locale::getDisplayName($lang)
。
請注意:引用者可能會被某些極客重寫,然後'$ router-> match()'會拋出一個異常,因爲沒有匹配。一個後備可能會很好:-) –
我還沒有做到這一點的形式,但只是在屏幕頂部的小旗子圖像。每個標誌都是指向當前頁面的鏈接,但URL中的雙字母語言代碼會被相應標誌的語言替換。我的佈局模板具有下面的代碼:
的replaceLanguageInUrl功能在我的枝條延伸類中定義:
public function getFunctions()
{
return array(
'replaceLanguageInUrl' => new \Twig_Function_Method($this, 'replaceLanguageInUrl'),
);
}
public function replaceLanguageInUrl($currentLanguage, $newLanguage, $url)
{
//EDIT BEGIN
if (strpos($url,$currentLanguage) == false) {
$url = getBaseUrl($url).'/'.$currentLanguage;
}
//EDIT END
return str_replace('/' . $currentLanguage . '/', '/' . $newLanguage . '/', $url);
}
當點擊一個標誌,同樣的頁面加載,但在新的語言。這也會在會話中自動設置新的語言。
我在本地做過,但比wdev的解決方案更簡單一些,我用一些圖片(標誌)作爲按鈕。單擊標誌時,將設置新的區域設置,並使用新語言刷新頁面(通過重定向)。您需要使用Symfony's translation system。下面是代碼:
控制器:
public function englishAction(Request $request)
{
$this->get('session')->setLocale('en_US');
return $this->redirect($request->headers->get('referer'));
}
public function chineseAction(Request $request)
{
$this->get('session')->setLocale('zh_CN');
return $this->redirect($request->headers->get('referer'));
}
public function frenchAction(Request $request)
{
$this->get('session')->setLocale('fr_FR');
return $this->redirect($request->headers->get('referer'));
}
模板:
<ul class="nav pull-right">
<li>
<a href="{{ path('english') }}"><img src="{{ asset('bundles/fkmywebsite/images/flag-en.png') }}" alt="English Language" height="30" width="18" /></a>
</li>
<li>
<a href="{{ path('chinese') }}"><img src="{{ asset('bundles/fkmywebsite/images/flag-cn.jpg') }}" alt="Chinese Language" height="30" width="18" /></a>
</li>
<li>
<a href="{{ path('french') }}"><img src="{{ asset('bundles/fkmywebsite/images/flag-fr.png') }}" alt="French Language" height="30" width="18" /></a>
</li>
</ul>
編輯:此解決方案可與Symfony2.0,爲Symfony2.1檢查this question
最簡單的方法我發現是直接在樹枝模板中做的。至少,它適用於2.2:
<ul class="lang-menu">
<li><a href="{{ path(app.request.get('_route'), app.request.get('_route_params')|merge({'_locale': 'ca'})) }}">Català</a></li>
<li><a href="{{ path(app.request.get('_route'), app.request.get('_route_params')|merge({'_locale': 'en'})) }}">English</a></li>
</ul>
是的,這是我爲每個頁面所做的,但是我也想讓用戶通過在列表中選擇他想要的語言。 – cvsoftware