【问题标题】:Symfony2-Rookie: Setting Path dynamicallySymfony2-Rookie:动态设置路径
【发布时间】:2012-01-05 11:00:40
【问题描述】:

好的,我设法将我的测试页的代码与 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?所以如果我目前在“关于我们”的英文页面上,我可以自动切换到德语页面关于我们,包括它的参数?有可能吗?还是我必须用路径对每个树枝页面/模板进行硬编码?

【问题讨论】:

    标签: internationalization routing symfony twig


    【解决方案1】:

    这描述了一个与您正在寻找的完全一样的扩展:http://blog.viison.com/post/15619033835/symfony2-twig-extension-switch-locale-current-route

    ScopeWideningInjectionException 可以通过注入 @service_container 来检索路由器和请求来修复,而不是直接注入它们。

    【讨论】:

      【解决方案2】:

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

      此扩展提供了一个新的 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/config 下的config.yml 文件中来启用此树枝扩展。

          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>
      

      希望这会有所帮助,这就是您正在寻找的。​​p>

      编辑:

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

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

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

      问候,
      马特

      【讨论】:

      • sweet...看起来很整洁,谢谢伙计..会尝试一下,如果它识别参数对我来说很重要....也许更简单的选择是每个用户在设置下定义他们的语言环境,并且它是从那里自动设置的....但我至少对于没有登录的页面需要这个。
      • 我已经尝试过您的解决方案。但我得到:'检测到范围扩大注入:定义“twig”引用了属于较窄范围的服务“tracker.twig.extension”。通常,将“twig”移动到“request”范围或通过注入容器本身并在每次需要时请求服务“tracker.twig.extension”来依赖提供者模式会更安全。但在极少数特殊情况下,您可以将引用设置为 strict=false 以消除此错误。'
      • 谢谢,仍然遇到同样的问题:ScopeWideningInjectionException ....必须是更简单的路径,例如 get_current_route 和 get_current params_ 或其他东西....它们 locale_ 始终保持不变...我只需要路线和参数。
      • 要获取路线,请执行$request-&gt;attributes-&gt;get('_route')。这将为您提供路线名称。要获取参数,请执行$request-&gt;attributes-&gt;all() 并过滤以下划线开头的每个值。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多