7

I want all URLs in my application to have a trailing slash. I have the following route in my route.yml:

foo_route:
    pattern:  /foo/{page}/
    defaults: { _controller: FooBundle:Foo:list, page: 1 }
    requirements:
      page:  \d+

Requests to '/foo/1/' work fine, however requests to '/foo/' are not matched because of the trailing slash in the URL pattern.

How can I define routes with trailing slashes and an optional parameter? I am aware I can define 2 different routes for the two cases, but I want to avoid that.

1
  • Whats so bad about haveing another route? Commented Apr 9, 2013 at 6:40

2 Answers 2

7

In a separate but related case, you can match the following three patterns:

/foo
/foo/
/foo/page/1

by eliminating the trailing backslash in the route and relaxing the regular expression to match 0 or more characters (*), instead of 1 or more (+):

foo_route:
    pattern:  /foo/{page}
    defaults: { _controller: FooBundle:Foo:list, page: 1 }
    requirements:
      page:  \d*

However that will not match /foo/page/1/

Sign up to request clarification or add additional context in comments.

Comments

1

Perhaps its easier to define the Controller over an annotation.

in route.yml:

MineTestBundle:
    resource: "@MineTestBundle/Controller/"
    type:     annotation

Then you can define the route direct in your controller.

/**
 * @Route("/foo")
 */
class FooController extends Controller {
    /**
     * @Route("/", name="_foo_index")
     * @Template()
     */
    public function indexAction() {
        return array();
    }

    /**
     * @Route("/{page}/", name="_foo_page")
     * @Template()
     */
    public function pageAction($page) {
        return array('page' => $page);
    }
}

Now when you try to access /foo you come to the indexAction and when you access /foo/1/ you come to the pageAction.

Edit:

Sorry for the misunderstanding. I've tried to reproduce your problem. The easiest way is to define 2 Routes in your config like this:

foo_route:
    pattern:  /foo/{page}/
    defaults: { _controller: AcmeDemoBundle:Foo:list }
    requirements:
        name: ".+"  

foo_route_foo:
    pattern:  /foo
    defaults: { _controller: AcmeDemoBundle:Foo:list, page: 1 }
    requirements:
        name: ".+"

In the Route without the parameter {page} You can set the page default to 1.

But here in the Cookbook is a chapter How to allow a "/" character in a route parameter so its possible to allow a / in the route so all that comes after /foo/123/234/ is in the variable $page and you can split them for yourself in your function.

8 Comments

Thank you for your comment, but there is in fact only one action with an optional parameter page.
pageAction ;) there is the parameter. Its the same like your example but you have a default indexAction when you leave the parameter blank.
No, you misunderstood. I want one route (with the optional parameter), pointing to one single action. I definitely want to avoid creating two routes and/or two actions.
@Gerry: Sorry for the misunderstanding i've reproduced your problem and edit my post.
Thank you, creating two routes is also the best solution I could come up with (as stated in the question), but also something I want to avoid. I suppose allowing a trailing slash inside the parameter itself is an option, but still a bit dirty.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.