【问题标题】:symfony 3 - generate current url with different localessymfony 3 - 生成具有不同语言环境的当前 url
【发布时间】:2016-05-08 09:34:06
【问题描述】:

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

<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 函数接受一个路由名称,在 Symfony 3 中似乎无法检索。

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

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

我怎么做这个东西?

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

【问题讨论】:

    标签: php routing locale symfony


    【解决方案1】:

    如何设置一个更改区域设置的路由操作,然后通过请求标头中的引用者重定向回原始页面(这将获得您以前的 url):

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

    这是未经测试的,但我之前已经实现过 - 我只是从内存中在我的手机上挖掘出来的。

    我确实实现了食谱中的“粘性”语言环境来处理语言环境切换: http://symfony.com/doc/current/cookbook/session/locale_sticky_session.html

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

    【讨论】:

    • 这不会在 URL 中设置新的语言环境。
    • 嗯,我想那是必须的。不想有 2 个重定向而不是 1 个,但是该死,这东西不是很灵活。
    • 我怀疑我的客户是否会接受这个解决方案,因为最终结果意味着所有语言都会有一个 url (/path/to/something/),这意味着用户无法共享以他们所需语言的页面,每个人都必须在需要时手动更改语言。如果没有语言前缀,我希望 URL 为 /en/path/to/smth//ru/path/to/smth/ 和隐含的 en,但如果用户打开了非本地化路径,似乎没有可靠的方法来猜测本地化路径的名称。
    • 粘贴区域设置到位后,您可以为同一操作设置多个路径 - 一个带有 _locale 参数,一个不带
    • 是的......我不得不重建它两次,然后才最终确定它!祝你好运!
    【解决方案2】:

    我做了一个相当简短的解决方案:制作 path()/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 中的路由匹配器完成的。

    【讨论】:

      【解决方案3】:

      @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 块中使用它。

      【讨论】:

      • 自从这个问题以来就没有使用过 Symfony,现在非常讨厌它。但也许其他人会发现它很有用。
      • @jurchiks 将来可能只有我一个人,当我忘记如何做到这一点时!
      • @jurchiks 在req..attributes.get 中只是一个小错误(双倍积分),但它工作正常,谢谢:)
      • @aalaap 知道如何在 Symfony 4 中做到这一点吗?
      • @marcuse 他们还没有实现这个??
      猜你喜欢
      • 1970-01-01
      • 2016-04-15
      • 1970-01-01
      • 2023-01-25
      • 1970-01-01
      • 2021-10-29
      • 1970-01-01
      • 1970-01-01
      • 2018-08-09
      相关资源
      最近更新 更多