Symfony2的新秀:设置路径动态

问题描述:

行,我成功地把代码为我testpage在结合JMSTranslationBundle切换语言像这样在树枝Symfony2的新秀:设置路径动态

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

这描述就像你正在寻找一个延伸:http://blog.viison.com/post/15619033835/symfony2-twig-extension-switch-locale-current-route

ScopeWideningInjectionException可以通过注入@service_container检索路由器和要求,而不是直接注入他们是固定的。

+0

工作就像一个魅力,感谢一百万人! – Confidence 2012-01-10 16:35:05

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

该扩展提供了一个新的分支函数,它将读取当前路由,当前参数,消除私有参数并生成相同的路由,但生成另一个区域设置。这里的树枝延伸问题:现在

<?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文件加载该服务定义这个树枝延伸。

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

现在你可以做到这一点的树枝提出不同版本的当前加载页面的:

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

希望这有助于,这是你在找什么。

编辑:

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

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

如果现在一切正常,请告诉我。

问候,
马特

+0

甜美...看上去非常整齐,谢谢man..will试试看,如果它能够识别参数,那么对我很重要....也许更简单的选项是每个用户在设置下定义它们的语言环境,并且它是自动的从那里设置....但我需要这至少为没有登录的页面。 – Confidence 2012-01-05 21:10:35

+0

我试过你的解决方案。但我得到:'范围扩展注入检测:定义“树枝”引用属于较窄范围的服务“tracker.twig.extension”。一般来说,将“twig”移动到范围“request”更安全,或者通过注入容器本身来依赖提供者模式,并在每次需要时请求服务“tracker.twig.extension”。然而,在罕见的特殊情况下,可能不需要,那么您可以将参考设置为strict = false,以便消除此错误 。 – Confidence 2012-01-06 14:36:59

+0

我将编辑我的答案以解决您的问题。 – Matt 2012-01-06 15:38:37