2012-02-21 4 views
24

Я пытаюсь создать наследование простого набора, как указано в here, и столкнулся с проблемой с маршрутами. Я использую аннотации для маршрутизации. Когда я регистрирую свой дочерний пакет в AppKernel.php, все мои пути родительских пакетов теряются.Symfony2 bundle inheritance потеряет родительские пучки маршрутов

Для того, что я понимаю из документации, Symfony2 должен искать все файлы, включая маршруты, сначала из дочернего пакета, а затем из родительского пакета. Теперь, когда этого не происходит, загружаются только контроллеры дочерних пучков.

В моем ребенке расслоения Bundle файл я реализовал функцию GetParent в соответствии с инструкциями, и в моем routing.yml у меня есть:

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

, которые прекрасно работали до наследования.

Я тестировал, что система работает нормально, если в нее включены все файлы контроллеров по-разному в routing.yml, но это кажется очень громоздким способом заставить наследование работать, поскольку я только хочу переопределить несколько частей родительского пакета (не все контроллеры).

Профайлер показывает оба моих пакета как активные.

ответ

16

Я нашел правильное решение для этой проблемы. Сегодня я также пытался переопределить родительский пакет, настроенный с помощью маршрутизации аннотаций, а также обнаружил, что родительские маршруты игнорировались, если маршрутизация анотаций импортировала весь пакет («@ SomeBundle/Controller»).

После небольшой отладки я обнаружил, что объяснение этого заключается в том, что если вы используете «@» в качестве префикса для контроллера, это перейдет к решателю ядра, который будет возвращать ТОЛЬКО дочерний ресурс, если родительский ресурс переопределен. Таким образом, решение состоит в том, чтобы предоставить полный путь пакета, учитывая, что ядро ​​попытается сопоставить ресурс с app/Resources, поэтому вам нужно будет добавить относительный каталог (../../) до фактического пути :

# 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 

Это будет работать, как и ожидалось: все родительские маршруты будут импортированы и будут переписаны все маршрутам, указанным в детском пачке.

+0

даже спустя 3 года я нахожу это полезным, хотя и немного неожиданным, даже если вы расширяете контроллеры в одном комплекте, родительские аннотации маршрутизации будут игнорироваться, поэтому, если вы хотите иметь общий код, вы должны прибегнуть к признаку или использовать SharedController, из которого они все распространяются, но без маршрутов в нем – DarkMukke

+0

Сохранено мое время. Большое спасибо за ваше решение –

+0

даже в 2017 году, это очень полезная информация. Танки для этого! –

0

С наложением наложения вы можете переопределить файлы родительского пакета.

Если вы создаете файл маршрутизации в том же месте, что и родители в своем пакете (если маршрутизация родительского файла находится в ParentBundle/Resources/config/routing.yml, и вы создаете файл маршрутизации в ChildBundle/Resources /config/routing.yml), он переопределит routing.yml родителя, и symfony будет использовать только routing.yml.

Я не пробовал, но если вы импортируете routing.yml родительского пакета в routing.yml дочернего пакета, вы можете решить вашу проблему. Поскольку маршрутизатор Symfony всегда будет выбирать первый соответствующий ему маршрут, вы можете переопределить определенный маршрут, написав соответствующий код маршрутизации поверх кода импорта.

+2

Кажется, что вы не можете импортировать childs routing.yml, потому что он создает круговую ссылку. – teemup

10

В дополнение к предыдущему ответу, мне также пришлось изменить имя routing.yml дочернего пакета (например, routing_child.yml), чтобы заставить его работать. Я предполагаю, что это потому, что Symfony полностью игнорирует файл маршрутизации родительского пакета, если имя идентично.

EDIT: Во многих случаях это также практично импортировать родительское расслоение маршрутов в файл маршрутизация ребенка расслоения, как это:

# routing_child.yml  
_parent: 
    resource: "@MyParentBundle/Resources/config/routing.yml" 
+0

это, пожалуй, самый простой способ imho, абсолютный или относительный патч, как описано ниже, не работает для меня – ivoba

+2

При использовании наследования пакетов Symfony переопределяет любой файл с тем же именем (будь то шаблон или файл конфигурации). – wdev

+0

Вот так я и решил это решить, с небольшой помощью от FOSUserBundle. –

2

Официальная документация говорит, что вы должны просто скопировать родительский файл маршрутизация вашего ребенка пачку :

Самый простой способ «переопределить» маршрутизацию пакета - никогда не импортировать его вообще. Вместо импорта маршрутизации стороннего пакета, просто скопировав этот файл маршрутизации в ваше приложение, измените его и импортируйте вместо него.

Кроме того, вы не можете включить файл маршрутизации пакета родителя с использованием символических имен «@ParentBundle», поскольку это имя разрешено «@ChildBundle».

Если вы действительно хотите включить файл родительских маршрутов, то вы должны использовать абсолютный путь к этому файлу или пути относительно текущего каталога, т. Е.:

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

или

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

Другое решением является симлинка файла маршрутизации родительского в ваш ребенке расслоение и включить его с более коротким путем, то есть:

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

, а затем

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

P.S. Надеюсь, они найдут лучший и менее уродливый способ переопределить и расширить маршрутизацию из родительского пакета, но теперь мы должны вывести некоторые из этих уродливых обходных решений.

+0

Должен сказать, хотя вы говорите, что это уродливо, символическая ссылка почти слишком уродлива, чтобы упомянуть. – mattalxndr