I have my own routing system I would like to send each call to one controller and in the controller I will detect which route/content I will display.
How to write this in the routing.yml so I can send each call to one controller?
Thanks!
I think you could do it with a catch all route like
catch_all:
path: /{catch_all}
defaults:
_controller: Your:Controller:AndAction
requirements:
catch_all: "[\s\S]+"
That should catch all paths and pass them into your controller as the "catch_all" parameter, from there you could do what ever you want with it.
Related
I am working with Symfony 6. The configuration of a route allows to add extra parameters which are passed to the controller:
index:
path: /somepage
controller: App\Controller\PageController::index
defaults:
title: 'Hello world!'
Is it possible to use a service as parameter? Something like:
defaults:
foo: '%some.container.parameter%' << Works, use container parameter?
logger: '#logger' << FAILS, use services as parameter?
This example does not work. While container parameters are correctly resolved, the services parameter is interpreted as string #logger instead of being resolved to the logger service.
Of course one could inject the complete service container into the PageController and use $this->container->get($logger); to get the services by its id. However, I found several sources, that injecting the services container is a bad idea which should be avoided.
So, is it possible to use a services as routing parameter?
Background
I would like to use a service parameter to make the controller more flexible when being used at different places.
For example the RedirectController can be used to create simple redirects without having to create a different controller for each redirected route.
Assume that the redirection of some routes is critical for some reason and needs more verbose logging and for example an alert notification via email.
Instead of creating different controllers and injecting different loggers, one could solve this by using different loggers as parameter:
legacy_one:
path: /somepage
controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController
defaults:
logger: '#defaultLogger'
legacy_two:
path: /otherpage
controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController
defaults:
logger: '#alertLogger'
I'm using ASP.net MVC4 with VWD Express 2010. I've set up an extra route to remove the extraneous /Home/ from URLs, as suggested for example here and here. I made sure to put them in the right order:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Home",
url: "{action}",
defaults: new { controller = "Home", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
This works as far as removing /Home/ is concerned, but now I get 404 when trying to access non-default controllers:
Server Error in '/' Application.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /LogItem/
I've tracked it down to the route, since if I remove the non-default one, it works fine again. I'm not sure what I'm doing wrong however, and by my understanding of other answers and the docs, this should work.
Edit: Since it's apparently not clear from my description, I added the "Home" route to be able to link to /About/ instead of /Home/About, etc. It was the suggested solution I found after googling. I basically want it to match actions implemented by HomeController with shorthand URLs (/{action}), as well as any other controller I also add in full (/{controller}/{action}/{optional id})
Routes are evaluated on a first-come, first-served basis. Your "Home" route basically says "If you see a URL with just one segment - grab it and handle it, then assume that segment is the action. When that happens, the second route you've registered doesn't get a chance to handle the request.
With the specific error as an example, you are requesting "/LogItem". The Home route kicks in, parses "LogItem" as the name of the action, and passes it to the default controller. Since that controller maybe doesn't have a LogIn action, a 404 is thrown.
One solution is to change the order of the routes. But even then, those two are overlapping, since the 2nd will also handle URLs with 1 segment, but interpret that segment as the controller. It will execute the default action (Index) rather than passing the handling to the next route.
Why do you need the first route? What are you trying to achieve? If you provide more context we can figure out a way to implement those routes.
When i call my bundle as a service, everything working fine.
When i give a route to my bundle's controller, __contstruct stops working and the variables coming from config.yml file reasoning this.
These are warnings, but i need to get work to set my variables.
Warning: Missing argument 1 for
ATL15\GoogleAnalyticsBundle\Controller\GoogleAnalyticsController::__construct(),
called in
/var/www/vsy-bio/app/cache/dev/jms_diextra/controller_injectors/ATL15GoogleAnalyticsBundleControllerGoogleAnalyticsController.php
on line 13 and defined in
/var/www/vsy-bio/src/ATL15/GoogleAnalyticsBundle/Controller/GoogleAnalyticsController.php
on line 22
You need to call your controller as a service aswell in your routing like this:
hello:
pattern: /hello
defaults: { _controller: acme.hello.controller:indexAction }
See the documentation chapter How to define Controllers as Services.
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.
I actually use automatic route generation for my api Rest, using the FOSRESTBundle, also I use NelmioApiDocBundle to generate the api doc.
To generate routes for the api this I have in my routing.yml
users:
type: rest
resource: Project\RESTBundle\Controller\UsersController
But for some actions I want to set my custom routing... If I try to add another route rule for an action it simply ignore it and generate the automatic route.
You have to declare the route with the same name right after the configuration you set. For example, the following works.
users:
type: rest
resource: Project\RESTBundle\Controller\UsersController
get_users:
pattern: /api/users/customUri.{_format}
defaults: { _controller: ProjectRESTBundle:Users:indexAction, _format: json }