Symfony2-Rookie:动态设置路径

发布于 2024-12-25 07:03:02 字数 581 浏览 0 评论 0原文

好的,我设法为我的测试页添加代码,以便与 JMSTranslationBundle 结合使用,在 twig 中切换语言,

<li>
<a href="{{ path("main", {"_locale": "en","name": name}) }}">
<img src="{{ asset('img/flags/gb.png') }}"></a></li>
<li>
<a href="{{ path("main", {"_locale": "de","name": name}) }}">
<img src="{{ asset('img/flags/de.png') }}"></a></li>

但这将适用于 path ("main") 我怎样才能使它动态地适用于我当前正在处理的页面/路由,包括所需的参数(在本例中 "name": name ?所以如果我当前在“关于我们”的英文页面上“,我可以自动切换到关于我们的德语页面,包括其参数?这可能吗?或者我是否必须使用路径对每个树枝页面/模板进行硬编码?

ok,i managed to put code for my testpage to switch languages in combination with JMSTranslationBundle like this in twig

<li>
<a href="{{ path("main", {"_locale": "en","name": name}) }}">
<img src="{{ asset('img/flags/gb.png') }}"></a></li>
<li>
<a href="{{ path("main", {"_locale": "de","name": name}) }}">
<img src="{{ asset('img/flags/de.png') }}"></a></li>

but this will be working for the path ("main")
how can i make it dynamically work for the page/route i am currently working on, including needed parameter (in this case "name": name ? so if i am currently on english page of "about us", i can automatically switch to german page of about us, including its parameters? is it possible? or do i have to hardcode each twig page/template with the paths?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

半仙 2025-01-01 07:03:02

这描述了一个与您正在寻找的扩展完全一样的扩展:

http://blog.viison.com/post/15619033835/symfony2-twig-extension-switch-locale-current-route ScopeWideningInjectionException 可以通过注入 @service_container 来检索路由器和请求来修复,而不是直接注入它们。

This describes an extension exactly like you are looking for: http://blog.viison.com/post/15619033835/symfony2-twig-extension-switch-locale-current-route

The ScopeWideningInjectionException can be fixed by injecting the @service_container to retrieve the router and request instead of injecting them directly.

全部不再 2025-01-01 07:03:02

硬编码是一个坏主意,这是可以实现的,但据我所知并不是开箱即用的。为了提供具有相同路径和参数但针对不同区域设置的 url,我所做的就是创建一个自定义树枝扩展来执行此操作。

此扩展提供了一个新的 twig 函数,它将读取当前路由、当前参数、消除私有参数并为另一个语言环境生成相同的路由。这里是有问题的 twig 扩展:

<?php

namespace Acme\WebsiteBundle\Twig\Extension;

use Symfony\Component\DependencyInjection\ContainerInterface;

class LocalizeRouteExtension extends \Twig_Extension
{
    protected $request;
    protected $router;

    public function __construct(ContainerInterface $container)
    {
        $this->request = $container->get('request');
        $this->router = $container->get('router');
    }

    public function getFunctions()
    {
        return array(
            'localize_route' => new \Twig_Function_Method($this, 'executeLocalizeRoute', array()),
        );
    }

    public function getName()
    {
        return 'localize_route_extension';
    }

    /**
     * Execute the localize_route twig function. The function will return
     * a localized route of the current uri retrieved from the request object.
     *
     * The function will replace the current locale in the route with the
     * locale provided by the user via the twig function.
     *
     * Current uri: http://www.example.com/ru/current/path?with=query
     *
     * In Twig: {{ localize_route('en') }} => http://www.example.com/en/current/path?with=query
     *          {{ localize_route('fr') }} => http://www.example.com/fr/current/path?with=query
     *
     * @param mixed $parameters The parameters of the function
     * @param string $name The name of the templating to render if needed
     *
     * @return Output a string representation of the current localized route
     */
    public function executeLocalizeRoute($parameters = array(), $name = null)
    {
        $attributes = $this->request->attributes->all();
        $query = $this->request->query->all();
        $route = $attributes['_route'];

        # This will add query parameters to attributes and filter out attributes starting with _
        $attributes = array_merge($query, $this->filterPrivateKeys($attributes));

        $attributes['_locale'] = $parameters !== null ? $parameters : \Locale::getDefault();

        return $this->router->generate($route, $attributes);
    }

    /**
     * This function will filter private keys from the attributes array. A
     * private key is a key starting with an underscore (_). The filtered array is
     * then returned.
     *
     * @param array $attributes The original attributes to filter out
     * @return array The filtered array, the array withtout private keys
     */
    private function filterPrivateKeys($attributes)
    {
        $filteredAttributes = array();
        foreach ($attributes as $key => $value) {
            if (!empty($key) && $key[0] != '_') {
                $filteredAttributes[$key] = $value;
            }
        }

        return $filteredAttributes;
    }
}

现在,您可以通过捆绑包加载此服务定义或直接加载到位于 app/configconfig.yml 文件中来启用此 twig 扩展>。

    services:
      acme.twig.extension:
        class: Acme\WebsiteBundle\Twig\Extension\LocalizeRouteExtension
        scope: request
        arguments:
          request: "@request"
          router: "@router"
        tags:
          -  { name: twig.extension }

现在您可以在 twig 中执行此操作,以提出当前加载页面的不同版本:

<a id='englishLinkId' href="{{ localize_route('en') }}">
  English
</a>
<a id='frenchLinkId' href="{{ localize_route('fr') }}">
  Français
</a>

希望这有帮助,这就是您正在寻找的。

编辑:

似乎不可能直接缩小树枝扩展的范围。为了避免这种情况,请始终注入依赖项容器,然后检索所需的服务。这应该通过更改 twig 扩展的构造函数定义和扩展的服务定义来反映。我编辑了之前的答案,检查新更新的构造函数定义和新服务定义。

另一种可能的解决方案是注入一个负责本地化路线的帮助服务。该辅助服务应该在请求范围内。事实上,这就是我的代码中的内容。我有一个 RoutingHelper 服务,它被注入到我的 twig 扩展中。然后,在 executeLocalizeRoute 方法中,我使用我的助手来完成这项艰苦的工作。

告诉我现在一切是否正常。

问候,
马特

Hardcoding is a bad idea and this is achievable but not out of the box as far as I know. What I did to provide an url with the same path and params but for a different locale was to create a custom twig extension to do it.

This extension provide a new twig function that will read the current route, the current parameters, eliminate private parameters and generate the same route but for another locale. Here the twig extension in question:

<?php

namespace Acme\WebsiteBundle\Twig\Extension;

use Symfony\Component\DependencyInjection\ContainerInterface;

class LocalizeRouteExtension extends \Twig_Extension
{
    protected $request;
    protected $router;

    public function __construct(ContainerInterface $container)
    {
        $this->request = $container->get('request');
        $this->router = $container->get('router');
    }

    public function getFunctions()
    {
        return array(
            'localize_route' => new \Twig_Function_Method($this, 'executeLocalizeRoute', array()),
        );
    }

    public function getName()
    {
        return 'localize_route_extension';
    }

    /**
     * Execute the localize_route twig function. The function will return
     * a localized route of the current uri retrieved from the request object.
     *
     * The function will replace the current locale in the route with the
     * locale provided by the user via the twig function.
     *
     * Current uri: http://www.example.com/ru/current/path?with=query
     *
     * In Twig: {{ localize_route('en') }} => http://www.example.com/en/current/path?with=query
     *          {{ localize_route('fr') }} => http://www.example.com/fr/current/path?with=query
     *
     * @param mixed $parameters The parameters of the function
     * @param string $name The name of the templating to render if needed
     *
     * @return Output a string representation of the current localized route
     */
    public function executeLocalizeRoute($parameters = array(), $name = null)
    {
        $attributes = $this->request->attributes->all();
        $query = $this->request->query->all();
        $route = $attributes['_route'];

        # This will add query parameters to attributes and filter out attributes starting with _
        $attributes = array_merge($query, $this->filterPrivateKeys($attributes));

        $attributes['_locale'] = $parameters !== null ? $parameters : \Locale::getDefault();

        return $this->router->generate($route, $attributes);
    }

    /**
     * This function will filter private keys from the attributes array. A
     * private key is a key starting with an underscore (_). The filtered array is
     * then returned.
     *
     * @param array $attributes The original attributes to filter out
     * @return array The filtered array, the array withtout private keys
     */
    private function filterPrivateKeys($attributes)
    {
        $filteredAttributes = array();
        foreach ($attributes as $key => $value) {
            if (!empty($key) && $key[0] != '_') {
                $filteredAttributes[$key] = $value;
            }
        }

        return $filteredAttributes;
    }
}

Now, you can enable this twig extension by loading this service definition either via your bundle or directly into the config.yml file located under app/config.

    services:
      acme.twig.extension:
        class: Acme\WebsiteBundle\Twig\Extension\LocalizeRouteExtension
        scope: request
        arguments:
          request: "@request"
          router: "@router"
        tags:
          -  { name: twig.extension }

And now you can do this in twig to propose a different version of the current loaded page:

<a id='englishLinkId' href="{{ localize_route('en') }}">
  English
</a>
<a id='frenchLinkId' href="{{ localize_route('fr') }}">
  Français
</a>

Hope this helps and that is what you are looking for.

Edit:

It seems that it is not possible to narrow the scope of a twig extension directly. To avoid this, inject instead the dependency container all along and then retrieve the required services. This should be reflected by changing constructor definition of the twig extension and the service definition for the extension. I edited my previous answer, check the new updated constructor definition and the new service definition.

Another possible solution would be to inject an helper service that is responsible of localizing the route. This helper service should be in the request scope. In fact, this is what I have in my code. I have a RoutingHelper service that is injected in my twig extension. Then, in the method executeLocalizeRoute, I use my helper to do the hard work.

Tell me if everything is working now.

Regards,
Matt

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文