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.
A trailing slash is a forward slash (“/”) placed at the end of a URL such as domain.com/ or domain.com/page/. The trailing slash is generally used to distinguish a directory which has the trailing slash from a file that does not have the trailing slash.
Conventionally, a trailing slash (/) at the end of a URL meant that the URL was a folder or directory. A URL without a trailing slash at the end used to mean that the URL was a file.
If your site has a directory structure, it's more conventional to use a trailing slash with your directory URLs (for example, example.com/directory/ rather than example.com/directory ), but you can choose whichever you like. Be consistent with the preferred version. Use it in your internal links.
“The slash after a hostname or domain name is irrelevant; you can use it or not when referring to the URL, it ends up being the same thing… However, a slash anywhere else is a significant part of the URL and will change the URL if it's there or not.”
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/
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With