Convention-based routing in Symfony2 - symfony

I'm trying to learn learn how routing works in Symfony2, and so far everything I've read has examples like this:
blog:
path: /blog/{page}
defaults: { _controller: AcmeBlogBundle:Blog:index, page: 1 }
This routes requests to /blog/123 to the AcmeBlogBundle Blog controller's "index" action, and passes the 123 parameter as the "page" parameter to that controller action. If no page parameter is passed, then the page defaults to 1.
That's all well and good, but what if you want to simply have a convention based routing system that passes things through like this:
/{bundle}/{controller}/{action}
So, for a URL like this:
/acme/blog/index
It would then call AcmeBlogBundle Blog controller's "index" action.
No specific routing configuration is necessary, it simply infers the bundle, controller, and action from the URL. So you can continue adding bundles, controllers, and actions, and you don't need to modify the routing configuration. It just works.
If this isn't possible, can you at least infer the controller and action from the URL? E.g., perhaps you need a route that specifically identifies the bundle, but can we get the controller and action from the URL?
I read through the Symfony "The Book" page about routing, and I couldn't figure out a way to do this.

No way. This was considered as bad practice and so it was removed from symfony.
But you should take a look at the #Route annotation, as it simplifies configuring routes in such a nice way. Directly attached to the action, there is no lack between config and code.

Related

Asp.Net MVC custom routing interrupt default routing

My routes are not working don't know why. When I try attribute routing it works for for that action but breaks default routing for other controller or actions. I only want to change routing for an index action method of a controller CMS I want it like [Route("{countrycode}/{id}")]. but when I do this default route breaks for other index action methods of other controllers.
For example: When I use [Route("{countrycode}/{id}")] on cms controller's index action then route breaks for Home and other controllers index action methods so I have to call the index methods explicitly like /Home/Index instead of /Home otherwise it throw an error. Thanks in advance.

Symfony redirect to dynamic route name

I'm using the Symfony CMF Routing Bundle to create dynamic routes (I'm using one example here):
$route = new Route('/dynamic-url');
$route->setMethods("GET");
$route->setDefault('_controller', 'AppBundle:MyRoute:getResponse');
$routeCollection->add('my-dynamic-route', $route);
The response is loaded from the getResponseAction() function inside the MyRouteController:
/**
* No annotations here, because I want the url to be dynamic from the database
*/
public function getResponseAction(Request $request) {
return $this->render('dynamic-page-template.html.twig');
}
When I go to '/dynamic-url', it works.
When in another controller, I want to redirect to this dynamic route, like this:
return $this->redirectToRoute('my-dynamic-route');
But I get this error: "None of the chained routers were able to generate route: Route 'my-dynamic-route' not found"
Also interesting: when I go to '/dynamic-url', the dev bar actually says that the Route name is 'my-dynamic-route'.
Edit
When I load all the routes, I don't see my dynamic route names:
$this->get('router')->getRouteCollection();
I think they should be in this list.
Since it's a dynamic route, which wasn't saved anywhere (like routing.yml ) it will be only availabe for Request where it has been defined. So at the end of Request your app will immediately "forget" about new Route generated at runtime.
When I load all the routes, I don't see my dynamic route names:
$this->get('router')->getRouteCollection();
I think they should be in this list.
Actualy No. It depends on where you call $this->get('router')->getRouteCollection();
Just try to call
dump($this->get('router')->getRouteCollection();)
right before the return statement in your Action where you're adding the my-dynamic-route route. I'm sure you'll see your my-dynamic-route in the list of routes, but if you call it anywhere else - you won't see it.
It's less about symfony rather about stateless nature of web (see Why say that HTTP is a stateless protocol?)
I started to think about this and pointed your question to an routing issue on symfony-cmf. You tagged with #symfony-cmf and i think this would be important feature for us.
I also think, when you persist your route with /my-route you should also ask the router for that name (or in case of the CMF with an content object with that a route.)
If you use the CmfRoutingBundle dynamic router, you should persist your routes to doctrine. The idea of dynamic here is that they can be created at runtime, e.g. in an admin interface or elsewhere by code. The DynamicRouter loads routes from the database.
If you use PHPCR-ODM, the route name is the repository id, typically something like /cms/routes/my-route and you can generate it with that name. If you have access to the route object loaded from the database, you can also generate from that, rather than the path. If you have to hardcode a path in your application, its an indication that probably a normally configured route would be better.
If you just add a route to the route collection on the fly, you would have to make sure that happens in each request, its only available when you add it. With the CMF ChainRouter you could register your own router that does that, but i would not know of a good use case for that. Either you know the route, then you can configure it in the routing.xml|yml|php config file. Or routes are loaded dynamically, in which point you should use DynamicRouter, potentially with a custom route loader.

Symfony route without controller

I have to work on a Symfony project that I never met before. There is a route that I'd like to figure out what script generates the result. Normally int the routing.yml the the _controller in the defaults tells this, but this route does not have any controller associated with:
vendorname_admin_generate_external_site_admin:
path: /admin/
host: "{current}.%vendorname_academic_base_host%"
defaults: {current: %vendorname_academic_base_subdomain%}
The two parameters are:
vendorname_academic_base_host: vendordomain.com
vendorname_academic_base_subdomain: developmentserver-vpn
Could you help me to understand what does this route definition do?
Because of the fact it is defining a specific host (ie, a domain name) as part of the route, makes me think that it's just an alias to an external website, that isn't actually in the same codebase. -- Also the fact its called 'external_site_admin'.
I've just added a similar route with a specific host, mine is still in the same codebase, but under a specific, shorter URL, but I defined my route as a template that I can use to setup as an alias.

Programmatically register routes at runtime

I want to be able to annotate some of my controllers with #SomethingProvider so that they automatically serve POST /{original-resource-url}/something URL and tie this URL to a generic handler.
Using a controller with wildcard mapping would not work because not all the resources will have that "something" collection available. Ex:
POST /user/something
POST /product/something
etc.
but not
POST /anything/something
My idea is to scan my controllers at runtime and look for that #SomethingProvider annotation so I can programmatically register the additional "something" endpoints.
I know it has to do with RequestMappingHandlerMapping but I can't figure out how to tap into it to add mappings.
Thanks geniuses

Html.BeginForm in WebApi - routing

I have a Web API project as part of my solution (also containing an MVC4 project) and within the Api project I am trying to post a form to the Values controller Post method (from a view also within the Api project).
Using Html.BeginForm() or Html.BeginForm("Post", "Values") posts to /Values/Post but I need it to go to /api/Values/Post
Any idea which overload or settings I need to post to the correct location?
I can hit all the action methods fine from fiddler (e.g. localhost/api/values).
You would need to use BeginRouteForm as link generation to Web API routes always depends on the route name. Also make sure to supply the route value called httproute as below.
#using (Html.BeginRouteForm("DefaultApi", new { controller="Values", httproute="true" }))
The API controller uses a different route to the default. It's supposed to be consumed from JS (AJAX) rather than a real form post so there's no obvious support for it in HtmlHelpers. Try:
Html.BeginForm("values", "api")
This would trick it into thinking "values" is the action and "api" is the controller. "Post" is inferred from the http method.

Resources