27

I am trying to create a simple bundle inheritance as instructed in here and ran into a problem with routes. I'm using annotations for routing. When I register my child bundle in AppKernel.php all my parent bundles routes are lost.

For what I understand from the documentation Symfony2 should look all files, including routes, first from the child bundle and then from the parent bundle. Now that is not happening, only child bundles controllers seems to be loaded.

In my child bundles Bundle file I have implemented getParent function as instructed, and in my routing.yml I have:

ParentBundle:
resource: "@Parent/Controller/"
type:     annotation
prefix:   /admin/

which worked fine before the inheritance.

I have tested that the system works fine if in include all controller files separetely in routing.yml but that seems very cumbersome way to make the inheritance to work as I only want to override few parts of the parent bundle ( not all controllers ).

Profiler is showing both of my bundles as active.

hakre
  • 193,403
  • 52
  • 435
  • 836
teemup
  • 624
  • 1
  • 8
  • 13

4 Answers4

19

I found the right solution for this issue. Today I was also trying to override a parent bundle configured with annotations routing and also found that parent routes were ignored if the anotation routing imported the whole bundle ("@SomeBundle/Controller").

After a little debugging I found that the explanation for this is that if you use "@" as prefix for the controller this will pass to the kernel resolver which will return ONLY the child resource if the parent resource has been overridden. So the solution is to provide the full path of the bundle, considering that the kernel will try to match the resource from app/Resources so you will have to add a relative directory (../../) before the actual path:

# app/config/routing.yml:
some_parent:
    resource: "../../src/Application/ParentBundle/Controller"
    type: annotation

# ChildBundle implements getParent() method to inherit from ParentBundle
some_child:
    resource: "@ChildBundle/Controller"
    type: annotation

This will work as expected: all parent routes will be imported and will be overridden by all routes specified in the child bundle.

Diego
  • 699
  • 6
  • 5
  • even 3 years later i find this useful, although a bit unexpected, even if you extend controllers in the same bundle, the parent routing annotions will be ignored, so if you want to have shared code, you must resort to a trait or use a SharedController that they all extend from but with no routes in it – DarkMukke Sep 28 '15 at 19:52
  • Saved my day. Thanks a lot for your solution – Rico Humme Jan 12 '17 at 10:39
  • even at 2017 this is a very useful information. Tanks for this! – enno.void Aug 21 '17 at 08:56
10

In addition to previous answer, I also had to change the name of the routing.yml of the child bundle (e.g. to routing_child.yml) to get it working. I assume this is because Symfony totally ignores the parent bundle routing file if the name is identical.

EDIT: In many cases it's also practical to import parent bundle routes into the child bundle routing file like this:

# routing_child.yml     
_parent:
    resource: "@MyParentBundle/Resources/config/routing.yml"
TomiS
  • 123
  • 7
  • this seems to be the easiest way imho, absolute or relative pathes, as described below didnt work for me – ivoba Jun 27 '12 at 15:09
  • 2
    When using bundle inheritance, Symfony overrides any file of the same name (whether it is a template or a config file). – wdev Oct 30 '12 at 14:18
  • This is how I ended up resolving it as well, with a little help from the FOSUserBundle – Rico Humme Jan 12 '17 at 10:39
2

The official documentation says that you shall just copy parent routing file to your child bundle:

The easiest way to "override" a bundle's routing is to never import it at all. Instead of importing a third-party bundle's routing, simply copying that routing file into your application, modify it, and import it instead.

Also, you cannot include parent's bundle routing file using symbolic names "@ParentBundle" because this name is resolved to "@ChildBundle".

If you really want to include parent routes file, then you shall use the absolute path to that file or path relative to current directory, i.e.:

# @YourChildBundle/Resources/routing.yml
YourParentBundle:
  resource: "/srv/www/example.com/src/Your/ParentBundle/Resources/routing.yml"

or

# @YourChildBundle/Resources/routing.yml
YourParentBundle:
  resource: "../../../../../Your/ParentBundle/Resources/routing.yml"

Another workaround is to symlink your parent routing file into your child bundle and include it with shorter path, i.e.:

cd YourChildBunde
ln -s ../../../../../Your/ParentBundle/Resources/routing.yml parent_routes.yml

and then

# @YourChildBundle/Resources/routing.yml
YourParentBundle:
  resource: "parent_routing.yml"

P.S. I hope they'll find some better and less uglier way to override and extend routing from parent bundle, but now we have to se some of those ugly workarounds.

Sergiy Sokolenko
  • 5,967
  • 35
  • 37
0

With bundle inheritance, you can override the parent bundle's files.

If you create a routing file in the same location as the parents in your bundle (if the routing of the parent file is at ParentBundle/Resources/config/routing.yml, and you create a routing file at ChildBundle/Resources/config/routing.yml), it will override the parent's routing.yml, and symfony will only use the child's routing.yml.

I haven't tried, but if you import the parent bundle's routing.yml in the child bundle's routing.yml, you can solve your problem. As Symfony router will always choose the first matching route it finds, you can override the specific route you want by writing the relevant routing code on top of the import code.

Hakan Deryal
  • 2,843
  • 1
  • 20
  • 19
  • 2
    It seems that you cant import the childs routing.yml because it creates a circular reference. – teemup May 11 '12 at 08:01