symfony 3 - 生成具有不同区域设置的当前网址

时间:2016-01-30 17:51:28

标签: php routing locale symfony

我想要做的是创建一个语言切换器模板,输出一个链接列表,如下所示:

<div class="language-switcher">
    <ul>
        {% for locale in allowed_locales %}
            <li>
                <a href="{{ path($get current route name here $, { '_locale': locale }) }}">
                    {{ locale|upper }}
                </a>
            </li>
        {% endfor %}
    </ul>
</div>

我遇到的主要问题是--Twig的内置path函数接受一个路径NAME,似乎无法在Symfony 3中检索。

另一个问题是 - 路由可能有其他参数,需要与_locale参数合并。从我在互联网上找到的代码(当然,对于symfony v2来说),使这项工作成为非常丑陋的代码,绝对不属于模板。

我认为实现这一目标的最佳方法是为此目的使用新的路由生成函数进行Twig扩展,但似乎也可能存在问题,因为path()函数位于另一个扩展中,我我不知道如何从我自己的扩展程序访问(我不太确定它也是一个好主意)。

我怎么能做这件事?

编辑:我也不想在每个操作中将数据传递给模板,因为它根本不是DRY。

3 个答案:

答案 0 :(得分:4)

@ jurchick的localized_path函数链接不再有效,所以我掀起了一个纯粹的Twig实现:

{% set req = app.request %}
{% for locale in allowed_locales %}
    {% if locale != req.getLocale() %}
        <link rel="alternate" hreflang="{{ locale }}" href="{{
            absolute_url(
                path(
                    req.attributes.get('_route'),
                    req.attributes.get('_route_params')|merge({'_locale': locale})
                )
            ) }}" />
    {% endif %}
{% endfor %}

此块实际上为当前页面生成备用语言链接。您可以在基本HTML块中使用它。

答案 1 :(得分:1)

如何更改区域设置的路由操作然后通过请求标头中的referer重定向回原始页面(这将获得您之前的URL):

public function localeChangerAction(Request $request, $locale)
{
    return $this->redirect($request->headers->get('referer'));
}

这是未经测试的,但我之前已经实现了这一点 - 我只是从内存中点击了我的手机。

我确实从cookbook实现了'sticky'语言环境来处理语言环境切换: http://symfony.com/doc/current/cookbook/session/locale_sticky_session.html

这可能对你有帮助,它适用于所有路线!

答案 2 :(得分:0)

我做了一个相当简短的解决方案:制作路径()/ url()Twig函数的本地化版本,自动检测当前路由并尝试查找其本地化版本并替换_locale参数。

https://gist.github.com/jurchiks/3b4e1bd249d7e8c1b60e

基本上,你在页眉或页脚的某处有这样的模板:

<h1>Current language: {{ app.request.getLocale() }}</h1>
<div class="language-switcher">
    <ul>
        {# allowed_locales comes from config #}
        {% for locale in allowed_locales %}
            <li>
                <a href="{{ localized_path('__current__', locale) }}">
                    {{ locale|upper }}
                </a>
            </li>
        {% endfor %}
    </ul>
</div>

或者,你可以这样做:

<a href="{{ localized_path('route_name') }}">

它将在当前区域设置中输出该特定路线。

使用这样的路线:

@Route("/", name="home")
@Route("/{_locale}/", name="home_lang", requirements={"_locale"="%allowed_locales%"})
public function indexAction()
...

@Route("/{_locale}/foo/", name="foo", requirements={"_locale"="%allowed_locales%"})
public function fooAction()
...

如果您打开http://127.0.0.1:8000/,则会输出Current language: en/en/, /ru/, /tk/。对于fooAction(),只允许显式语言环境,输出相同。 显然,显式语言环境将被正确设置,这是由Symfony中的路由匹配器完成的。