Symfony2语言选择器

cvs*_*are 12 php symfony

我想集成一个简单的HTML表单,允许用户更改Symfony2 Web应用程序的语言(即从页面en/faq转到fr/faq).如何以适当的方式做到这一点?

我找到了一个很好的方法来使用Symfony而不是Symfony2:http://symfony.com/blog/play-with-the-user-language

Wai*_*... 31

我找到的最简单的方法是直接在树枝模板中进行.至少,它适用于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>
Run Code Online (Sandbox Code Playgroud)


wde*_*dev 11

您需要$this->get('session')->setLocale($locale)在控制器内调用(将'session'替换为Symfony 2.1的'request').

我创建了一个表单,我传递了一系列语言:

<?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';
    }
}
Run Code Online (Sandbox Code Playgroud)

我将此表单提交给控制器中的单独操作,我在其中设置区域设置并返回重定向到最后一页:

<?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);
    }
}
Run Code Online (Sandbox Code Playgroud)

使用任何有效的区域设置(在创建表单时将它们作为"语言"选项传递),前提是已启用PHP intl扩展.如果不是,则需要\Locale::getDisplayName($lang)使用手动创建的区域设置名称列表进行替换.


小智 5

我没有使用表单,但只是在屏幕顶部使用小旗图像.每个标志都是指向当前页面的链接,但URL中的双字母语言代码被相应标志的语言替换.我的布局模板具有以下代码:

{% for language, description in languages %}
    <a href="{{ replaceLanguageInUrl(app.session.locale, language, app.request.uri) }}">
    <img src="{{ asset('images/flag_' ~ language ~ '.png') }}" alt="" title="{{ description }}"/>
    </a>
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

replaceLanguageInUrl函数在我的Twig扩展类中定义:

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);
}
Run Code Online (Sandbox Code Playgroud)

单击标志时,将加载相同的页面,但使用新语言.这也将自动在会话中设置新语言.


Mag*_*der 2

使用_locale路由定义中的参数会自动设置用户区域设置。

请参阅http://symfony.com/doc/current/book/translation.html#the-locale-and-the-url