I was reviewing the symfony 3.4 routing page. I have a misunderstanding if anyone can help me. So say you have the following:
In Your controller:
class BlogController extends Controller
{
/**
* Matches /blog exactly
*
* #Route("/blog", name="blog_list")
*/
public function listAction()
{
// ...
}
}
And in your routing.yml:
blog_list:
path: /blog
defaults: { _controller: AppBundle:Blog:list }
Would you be able to delete the route annotation above the function. Because now the routing is being handled by the routing.yml?
Many thanks
You must choose one of this methods to set route for current url "/blog"
In Symfony Routing can be declare using YAML, XML, PHP or annotation. It is recommended you stick with only one but you can use multiple approaches in a single project.
Official doc for routing Symfony Routing
and the answer to your question is, I would say yes you could delete the annotation.
Because now the routing is being handled by the routing.yml
for the big project, I prefer YML routing.
Related
In my application, I use Symfony 4. I want Symfony to search for controllers in two directories: A and B. I found something like this:
controllers:
resource: '../src/DirectoryA/Controller/'
type: annotation
, but it only works for one directory. How can I have Symfony to search for controllers in two directories?
Regards
In your config/services.yaml
App\DirectoryA\Controller\: # assuming you have namespace like that
resource: '../src/DirectoryA/Controller'
tags: ['controller.service_arguments']
App\DirectoryB\Controller\: # assuming you have namespace like that
resource: '../src/DirectoryB/Controller'
tags: ['controller.service_arguments']
This will add next directory for service arguments. Thats answers your questions based In directory, what you have posted is routing file, in there would be similiar
controllers_a:
resource: '../src/DirectoryA/Controller/'
type: annotation
controllers_b:
resource: '../src/DirectoryB/Controller/'
type: annotation
The accepted answer is of course completely correct.
However, once you move from having one controller directory to multiple directories, updating your services.yaml file can be a bit of a pain. Even having to have directories specifically for controllers can be limiting.
Here is an alternate approach which allows creating controllers wherever you want and automatically tagging them.
Start with an empty controller interface for tagging.
interface ControllerInterface {}
Now have all your controllers implement the interface
class Controller1 implements ControllerInterface { ...
class Controller2 implements ControllerInterface { ...
And then adjust the kernel to automatically tag all your controller interface classes with the controller tag.
# src/Kernel.php
protected function build(ContainerBuilder $container)
{
$container->registerForAutoconfiguration(ControllerInterface::class)
->addTag('controller.service_arguments')
;
}
And presto. You can create your controllers wherever you want with nothing in services.yaml.
Update:
If you would like to avoid editing Kernel.php then you can use the _instanceof functionality in your services.yaml file.
#config/services.yaml
services:
_instanceof:
App\Contract\ControllerInterface:
tags: ['controller.service_arguments']
Another Update: As long as your controller extends Symfony's AbstractController then no additional tagging is needed. You can even delete the default controller lines in the default services.yaml file if you want.
I've got a question about the inheritance of annotations in symfony.
Class A:
abstract class AController
{
/**
* Test action
* #Route("/", name="test")
* #Template("...")
*/
public function testAction()
{
...
}
}
My question is if it is possible from Class B not only to inherit the function but also the route annotation. Or what a nice workaround would be. Something like:
class BController extend AbstractController
{
public function testAction(){
return parent::testAction();
}
}
I was looking for a similar solution for an admin subdomain on a project I'm working on. First, I tried to use your method and realized it isn't supported. So I set updated my configuration instead. The following configuration automatically restricts all routes in the /src/Controller/Admin directory to my admin subdomain and prefixes all the route names with "admin_".
# /config/routes/annotations.yaml
controllers:
resource: ../../src/Controller/**/*
type: annotation
exclude: ../../src/Controller/Admin
admin:
resource: ../../src/Controller/Admin/
type: annotation
host: admin.%site_name%
name_prefix: admin_
....
There's a couple things to note here. First, "%site_name%" is a parameter defined in my project. Second, there seems to be a bug with the exclude option on route configurations where it only works if you use a glob pattern for resource option. Hence the "../../src/Controller/**/*".
This question is pretty old, but hopefully this helps someone.
I want to learn symfony and I start to create a small application. I have a question related to the routes. So, I have in my project the routes :
/admin/homepage, /admin/news, admin/galery
No if I write in url /admin, this route doesn't exist and I get as error No route found for "GET /admin/". Exist a way to check if route doesn't exist and redirect to another route for example ? Thx in advance and sorry for my english
My routes :
news_all:
path: /news/all/{page}
defaults: { _controller: AppAdminBundle:News:all, page: 1 }
requirements:
page: \d+
_method: GET|POST
news_add:
path: /news/add
defaults: { _controller: AppAdminBundle:News:add }
In your case the best solution would be to override default ExceptionController and add custom logic there, e.g. redirection to other page - according to the docs: http://symfony.com/doc/current/cookbook/controller/error_pages.html#overriding-the-default-exceptioncontroller
# app/config/config.yml
twig:
exception_controller: AppBundle:Exception:showException
Note:
Instead of creating a new exception controller from scratch you can, of course, also extend the default ExceptionController. In that case, you might want to override one or both of the showAction() and findTemplate() methods. The latter one locates the template to be used.
Symfony's good practise are to set rout in your controller, using annotations
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
and
/**
* #Route("/news/add", name="news_add")
*/
public function addAction()
{
// ...
}
Also, with annotation, you can set rout for a whole controller.
Which is, in your case, what you're looking for.
/**
* #Route("/admin")
*/
class NewsController extends Controller
{
/**
* #Route("/news/add", name="news_add")
*/
public function addAction()
{
// ...
}
}
Also, I advice you to take a look at #Template annotation.
Else, to answer your question, I think you can make a custom twig function (check this link for more information). Function that checks is the given name a valid route:
function routeExists($name)
{
// I assume that you have a link to the container in your twig extension class
$router = $this->container->get('router');
return (null === $router->getRouteCollection()->get($name)) ? false : true;
}
In Symfony is it possible to access a controller through a route that potentially can contain indefinite number of slug, taking advantage from internal routing system?
e.g.
my_route:
pattern: /{slug_parent}/{slug_child}/{slug_nephew}/{slug_...}/...
as
www.mydomain.com/math/arithmetic/fractions
but also
www.mydomain.com/tech/android
It can be done, but instead of creating routes in config YML I would recommend to use #Route annotations. Add annotations in the controller class, like this:
/**
* #Route("/{slug_parent}/{slug_child}")
* #Route("/{slug_parent}/{slug_child}/{slug_nephew}/")
* #Route("/{slug_parent}/{slug_child}/{slug_nephew}/{slug_...}/")
*/
public function yourControllerAction()
{
...
}
http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/routing.html
I just downloaded symfony2 and am beginning to play with routing via annotations. I have my app/config/routing.yml set in the bundle I created to use annotations, and have deleted the Acme bundle and all routing references to it. That said, I've tried creating a couple different route annotations in my controller like #Route("/") and #Route("/hello/{name}") but I'm always greeted with a 404 error (using the dev environment). If I add the route in routing.yml it works just fine even though the routing is configured to use annotations. For whatever reason, my annotations are seemingly being ignored.
Here is my app/config/routing.yml:
DanDefaultBundle:
resource: "#DanDefaultBundle/Controller/"
type: annotation
prefix: /
And here is my controller method:
/**
* #Route("/")
* #Template()
*/
public function indexAction()
{
return array('name' => 123);
}
I've included the Sensio\Bundle\FrameworkExtraBundle\Configuration\Route namespace - everything as far as I can tell is correct with what I've seen in the documentation. What am I overlooking that's causing symfony2 to seemingly ignore my routing annotations? Again, if I add the routes to the routing yaml everything works so my bundle is working - but annotations seem to be ignored.
Thanks!
Dan
UPDATE:
It looks like I had to add the routes to routing_dev.yml in addition to routing.yml since I was operating in the dev environment. I suppose that's so you have have different routes in-between development and production? I suppose special care will have to be taken to make sure those routes stay in sync?
You accidentally removed the inclusion of routing.yml from routing_dev.yml.
if you use Route Prefix in your routing.yml
you must declare about your prefix above your class declaration like that :
/**
* #Route("/")
*/
class PostController extends Controller
{
/**
* #Route("/")
* #Template()
*/
public function indexAction()
{
}
/**
* #Route("{id}")
* #Template()
*/
public function showAction($id)
{
}
}
Like into Sensio FrameworkExtra Bundle Documentation