Internationalization Symfony2新手:动态设置路径

Internationalization Symfony2新手:动态设置路径,internationalization,routing,symfony,twig,Internationalization,Routing,Symfony,Twig,好的,我设法将测试页面的代码与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", {"_loca

好的,我设法将测试页面的代码与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>
  • 但这将适用于
    路径(“main”)

    如何使其在我当前处理的页面/路线上动态工作,包括所需的参数(在本例中为
    “name”:name
    ?如果我当前在“about us”的英文页面上,我可以自动切换到about us的德语页面,包括它的参数?可能吗?或者我必须用路径对每个小树枝页面/模板进行硬编码吗?

    硬编码是一个坏主意,这是可以实现的,但据我所知不是现成的。我所做的是提供一个具有相同路径和参数但用于不同语言环境的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;
        }
    }
    
    现在,您可以在twig中执行此操作,以提出当前加载页面的不同版本:

    <a id='englishLinkId' href="{{ localize_route('en') }}">
      English
    </a>
    <a id='frenchLinkId' href="{{ localize_route('fr') }}">
      Français
    </a>
    
    
    
    希望这对你有所帮助,这就是你想要的

    编辑:

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

    另一种可能的解决方案是注入一个负责路由本地化的助手服务。这个助手服务应该在请求范围内。事实上,这就是我的代码中的内容。我有一个
    routinghelp
    服务注入到我的小树枝扩展中。然后,在方法
    executeLocalizeRoute
    中,我使用我需要一个助手来做这项艰苦的工作

    告诉我现在是否一切正常

    问候,

    Matt

    硬编码是一个坏主意,这是可以实现的,但据我所知不是现成的。我所做的是提供一个具有相同路径和参数的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;
        }
    }
    
    现在,您可以在twig中执行此操作,以提出当前加载页面的不同版本:

    <a id='englishLinkId' href="{{ localize_route('en') }}">
      English
    </a>
    <a id='frenchLinkId' href="{{ localize_route('fr') }}">
      Français
    </a>
    
    
    
    希望这对你有所帮助,这就是你想要的

    编辑:

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

    另一种可能的解决方案是注入一个负责路由本地化的助手服务。这个助手服务应该在请求范围内。事实上,这就是我的代码中的内容。我有一个
    routinghelp
    服务注入到我的小树枝扩展中。然后,在方法
    executeLocalizeRoute
    中,我使用我需要一个助手来做这项艰苦的工作

    告诉我现在是否一切正常

    问候,

    Matt

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


    通过注入
    @service\u容器
    来检索路由器和请求,而不是直接注入它们,可以修复
    作用域加宽InjectionException

    这描述了一个与您所寻找的完全相同的扩展:


    作用域加宽injectionException
    可以通过注入
    @service\u container
    来检索路由器和请求,而不是直接注入它们来修复。

    sweet…看起来非常整洁,谢谢你。会尝试一下,如果它能识别参数,对我来说很重要……也许更简单的选择是每个用户定义设置下的ir区域设置,并从那里自动设置…但我至少需要在没有登录的页面上使用此设置。我尝试了您的解决方案。但我得到:'范围扩大注入检测:定义“twig”引用属于较窄范围的服务“tracker.twig.extension”。通常,移动“twig”更安全通过注入容器本身并请求服务“tracker.twig.extension”来限定“request”的范围,或者依赖提供者模式每次都需要。在极少数情况下,特殊情况下可能不需要这样做,然后您可以将引用设置为strict=false以消除此错误。“谢谢,仍然会遇到相同的问题:ScopeWidenginInjectionException…必须是一个更简单的路径,例如get_current_route和get_current params_u或其他什么……它们的locale_u始终是常量a。”nyway…我只需要路由和参数。要获取路由,请执行
    $request->attributes->get(“\u route”)
    。这将为您提供路由名称。要获取参数,请执行
    $request->attributes->all()
    并过滤每个以下划线开头的值。sweet…看起来真的很整洁,谢谢你。我会尝试一下,如果它能识别参数,这对我来说很重要。也许更简单的选择是每个用户在设置下定义他们的区域设置,然后自动设置。但我至少需要在没有登录的页面上使用。我已经尝试过了您的解决方案。但我得到:'范围扩大注入检测:定义“twig”引用服务“tracker.twig.extension”,该服务属于较窄的范围。通常,将“twig”移动到范围“request”或