【问题标题】:Variable on a prefix on symfony2 routingsymfony2 路由前缀上的变量
【发布时间】:2014-01-27 18:08:41
【问题描述】:

我需要在我的 symfony2 路由的前缀上添加一个变量,以便我可以在主路由文件中执行类似的操作:

//app/config/routing.yml
god:
    resource: "@Acme/DemoBundle/Resources/config/routing.yml"
    prefix: /god/{religion}

然后在捆绑路由文件中出现这样的内容:

gods_route_to_heaven:
    path: /path_to_heaven
    defaults: { _controller: AcmeBlogBundle:God:show }

这样我就可以访问这样的路径:

/god/Christianity/path_to_heaven
/god/Islam/path_to_heaven
/god/Hinduism/path_to_heaven

等等。

如果我在控制台上输入app/console route:debug | grep api,我会得到正确的路由/god/{religion}/path_to_heaven,因此路由生成正确。

但是当我尝试通过将参数作为输入放在操作函数中来获取控制器中的参数时,如下所示:

public function showAction($religion)

路径被损坏并转储路径我看到它被重复:/god/{religion}/path_to_heaven/{religion}

那么我如何从控制器内部获取 $religion 变量?

【问题讨论】:

    标签: symfony routing


    【解决方案1】:

    你试过了吗?

    //app/config/routing.yml
    god:
        resource: "@Acme/DemoBundle/Resources/config/routing.yml"
        prefix: /god
    

    然后在捆绑路由文件中出现这样的内容:

    gods_route_to_heaven:
        path: /{religion}/path_to_heaven
        defaults: { _controller: AcmeBlogBundle:God:show }
    

    让我知道它是否有效。

    【讨论】:

    • 是的,这行得通,但我试图避免将 {religion} 占位符放在 /god 下的每个 rout 中...想象一下 /god 下有 100 条路由,我必须添加{religion} 占位符。相反,如果我将它添加到前缀中,我只会添加一次。
    【解决方案2】:

    您需要的可能解决方案是:

    文件:src/Acme/CoreBundle/Twig/PathExtension.php

    <?php
    
    namespace Acme\CoreBundle\Twig\Extension;
    
    use Symfony\Bundle\FrameworkBundle\Routing\Router;
    use Symfony\Component\HttpKernel\Event\GetResponseEvent;
    use Symfony\Component\HttpKernel\HttpKernel;
    
    class PathExtension extends \Twig_Extension
    {
    
        private $request;
        private $router;
    
        public function __construct(Router $router) {
            $this->router = $router;
        }
    
        public function onKernelRequest(GetResponseEvent $event) {
            if ($event->getRequestType() === HttpKernel::MASTER_REQUEST) {
                $this->request = $event->getRequest();
            }
        }
    
        public function getFunctions()
        {
            return array(
                'path_route' => new \Twig_Function_Method($this, 'getPath')
            );
        }
    
        public function getPath($name, $parameters = array())
        {
            $parameters = array_merge($parameters, [
                'religion' => $this->request->get('religion'),
            ]);
    
            return $this->router->generate($name, $parameters, false);
        }
    
        public function getName()
        {
            return 'twig_path_route_extension';
        }
    
    }
    

    配置即服务:

    文件:src/Acme/CoreBundle/Resources/config/services.yml

    services:
        twig.path_route_extension:
            class: Acme\CoreBundle\Twig\PathExtension
            tags:
                - { name: twig.extension }
                - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
            arguments: [@router]
    

    设置您的路由选项:

    文件:app/config/routing.yml

    _acme_religion:
        resource: "@AcmeCoreBundle/Resources/config/routing.yml"
        prefix:   /god/{religion}/
    

    然后你可以在模板和routing.yml中使用它,例如:

    _religion_pathheaven:
        path:     /path_to_heaven
        defaults: { _controller: AcmeCoreBundle:System:getpathheaven }
    

    然后,在您的模板中,您可以使用:

    <a href="{{ path_route('_religion_pathheaven') }}">
      Link Path to heaven.
    </a>
    

    参考资料:

    Pass path parameters automatically http://blog.viison.com/post/15619033835/symfony2-twig-extension-switch-locale-current-route

    【讨论】:

      【解决方案3】:

      你可以这样解决这个问题-

      god:
          resource: "@Acme/DemoBundle/Resources/config/routing.yml"
          prefix: /god/{_locale}/
      

      这里不用改--

      gods_route_to_heaven:
          path: /path_to_heaven
          defaults: { _controller: AcmeBlogBundle:God:show }
      

      在这里修改--

          public function showAction(){
             // below line is extra if you need
               $post   = $this->get('request')->request->all();
               $religion = $post['religion']; 
          }
      

      我没有测试这段代码,但所有过程都得到了很好的证明。如果您发现任何问题,请讨论。

      你也可能会看到这个问题,它会对你很有帮助Symfony2 Route global {_locale} requirements

      【讨论】:

      • 是的,这可行,但这不是最好的方法。如果我想将 _locale 用于它的真正目的怎么办? _locale 是一个特殊的参数...
      【解决方案4】:

      可能为时已晚,但它可以帮助其他人
      我在使用 Symfony 和 FOSUserBundle 时遇到了同样的问题。
      在 FOSUserBundle 中,配置文件链接是:

      site_url/profile/
      site_url/profile/编辑
      site_url/profile/更改密码

      我有一个管理和仪表板面板,我希望链接在管理面板中

      site_url/admin/profile/
      site_url/admin/profile/edit
      site_url/admin/profile/更改密码

      在用户仪表板中

      site_url/dashboard/profile/
      site_url/dashboard/profile/edit
      site_url/dashboard/profile/更改密码

      要获得这种行为,无需 EventListener 和 TwigExtesion
      非常简单 这里的解决方案:

      替换

      fos_user:
          resource: "@FOSUserBundle/Resources/config/routing/all.xml"
      

      通过

      fos_user_security:
          resource: "@FOSUserBundle/Resources/config/routing/security.xml"
      fos_user_registration:
          resource: "@FOSUserBundle/Resources/config/routing/registration.xml"
      fos_user_resetting:
          resource: "@FOSUserBundle/Resources/config/routing/resetting.xml"
      fos_user_change_password:
          resource: "@FOSUserBundle/Resources/config/routing/change_password.xml"
          prefix:   /{prefix}/profile 
      fos_user_profile:
          resource: "@FOSUserBundle/Resources/config/routing/profile.xml"
          prefix:   /{prefix}/profile
      

      在模板中使用:

      <a href="{{ path('fos_user_profile_show', {'prefix': 'dashboard'}) }}">Show Profile</a>
      <a href="{{ path('fos_user_profile_edit', {'prefix': 'dashboard'}) }}">Edit Profile</a>
      <a href="{{ path('fos_user_change_password', {'prefix': 'dashboard'}) }}">Change Password</a>
      

      或者你想要的任何其他前缀
      现在,如果您使用例如更改密码链接,您将收到此错误

      在渲染模板期间引发了异常(“一些 缺少强制参数(“前缀”)来生成 URL 路由“fos_user_change_password”。”)在 FOSUserBundle:ChangePassword:changePassword_content.html.twig 在行 3.

      您可以像这样在模板中添加前缀:
      替换

      <form action="{{ path('fos_user_change_password') }}" {{ form_enctype(form) }} method="POST" class="fos_user_change_password"> 
      

      通过

      <form action="{{ path('fos_user_change_password', {'prefix': app.request.attributes.get('prefix') }) }}" {{ form_enctype(form) }} method="POST" class="fos_user_change_password">
      

      这会给你这个错误

      缺少一些强制参数(“前缀”)来生成 URL 路由“fos_user_profile_show”。

      我找到的最终解决方案是覆盖控制器
      只需将洞控制复制到您的应用控制器文件夹中,更改命名空间并替换

      if (null === $response = $event->getResponse()) {
                      $url = $this->generateUrl('fos_user_profile_show');
                      $response = new RedirectResponse($url);
                  }
      

      通过

      if (null === $response = $event->getResponse()) {
                      $url = $this->generateUrl('fos_user_profile_show',array('prefix'=>$request->get('prefix')));
                      $response = new RedirectResponse($url);
                  }
      

      在您不需要该操作的形式中,它将是

      <form  {{ form_enctype(form) }} method="POST" class="fos_user_change_password">
      

      【讨论】:

        【解决方案5】:

        你可以这样获取宗教值:

        use Symfony\Component\HttpFoundation\Request;
        
        ...
        
        public function showAction(Request $request){
           $yourReligionIs = $request->get('religion');
        }
        

        【讨论】:

          猜你喜欢
          • 2015-08-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-04-30
          相关资源
          最近更新 更多