2012-02-21 39 views
24

Tôi đang cố gắng tạo một gói thừa kế đơn giản theo hướng dẫn trong here và gặp sự cố với các tuyến đường. Tôi đang sử dụng chú thích để định tuyến. Khi tôi đăng ký gói con của tôi trong AppKernel.php, tất cả các gói cha mẹ của tôi bị mất.Kế thừa gói Symfony2 mất các gói cha mẹ tuyến

Đối với những gì tôi hiểu từ tài liệu Symfony2 nên xem tất cả các tệp, bao gồm các tuyến, trước tiên từ gói con và sau đó từ gói chính. Bây giờ điều đó không xảy ra, chỉ có các bộ điều khiển bó con dường như được nạp.

Trong con tôi bó tập tin Bundle tôi đã thực hiện getParent chức năng theo hướng dẫn, và trong routing.yml của tôi, tôi có:

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

mà làm việc tốt trước khi thừa kế.

Tôi đã thử nghiệm rằng hệ thống hoạt động tốt nếu bao gồm tất cả các tệp điều khiển tách biệt trong routing.yml nhưng điều đó có vẻ rất cồng kềnh để làm cho kế thừa hoạt động vì tôi chỉ muốn ghi đè vài phần của gói gốc (không phải tất cả bộ điều khiển).

Trình thu thập thông tin hiển thị cả hai nhóm của tôi là đang hoạt động.

Trả lời

16

Tôi đã tìm ra giải pháp phù hợp cho vấn đề này. Hôm nay tôi cũng đang cố gắng ghi đè lên một gói cha được định cấu hình với định tuyến chú thích và cũng thấy rằng các tuyến đường mẹ bị bỏ qua nếu định tuyến anotation đã nhập toàn bộ gói ("@ SomeBundle/Controller").

Sau khi gỡ lỗi một chút, tôi thấy rằng giải thích cho điều này là nếu bạn sử dụng "@" làm tiền tố cho bộ điều khiển, nó sẽ chuyển tới bộ giải hạt nhân sẽ trả về CHỈ tài nguyên con nếu tài nguyên chính bị ghi đè. Vì vậy, giải pháp là cung cấp đường dẫn đầy đủ của gói, xem xét hạt nhân sẽ cố gắng kết hợp tài nguyên từ ứng dụng/Tài nguyên để bạn sẽ phải thêm một thư mục tương đối (../../) trước đường dẫn thực tế :

# 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 

Điều này sẽ hoạt động như mong đợi: tất cả các tuyến đường mẹ sẽ được nhập và sẽ bị ghi đè bởi tất cả các tuyến được chỉ định trong gói con.

+0

thậm chí 3 năm sau, tôi thấy điều này hữu ích, mặc dù một chút bất ngờ, ngay cả khi bạn mở rộng các bộ điều khiển trong cùng một gói, các chú thích định tuyến gốc sẽ bị bỏ qua, vì vậy nếu bạn muốn có mã chia sẻ, bạn phải sử dụng một đặc điểm hoặc sử dụng một SharedController mà tất cả chúng đều mở rộng nhưng không có tuyến đường nào trong đó – DarkMukke

+0

Lưu lại ngày của tôi. Cảm ơn rất nhiều vì giải pháp của bạn –

+0

ngay cả ở năm 2017, đây là một thông tin rất hữu ích. Xe tăng cho việc này! –

0

Với gói thừa kế, bạn có thể ghi đè lên các tệp của gói gốc.

Nếu bạn tạo tệp định tuyến ở cùng vị trí với cha mẹ trong gói của bạn (nếu định tuyến tệp gốc ở ParentBundle/Resources/config/routing.yml và bạn tạo tệp định tuyến tại ChildBundle/Resources /config/routing.yml), nó sẽ ghi đè lên routing.yml của cha và symfony sẽ chỉ sử dụng routing.yml của trẻ.

Tôi chưa thử, nhưng nếu bạn nhập routing.yml của gói cha trong routing.yml của gói con, bạn có thể giải quyết vấn đề của mình. Vì bộ định tuyến Symfony sẽ luôn chọn tuyến phù hợp đầu tiên mà nó tìm thấy, bạn có thể ghi đè lên tuyến đường cụ thể mà bạn muốn bằng cách viết mã định tuyến có liên quan ở trên cùng của mã nhập.

+2

Dường như bạn không thể nhập tệp routing.yml của con vì nó tạo tham chiếu vòng tròn. – teemup

10

Ngoài câu trả lời trước, tôi cũng phải thay đổi tên của routing.yml của gói con (ví dụ: routing_child.yml) để làm cho nó hoạt động. Tôi cho rằng điều này là bởi vì Symfony hoàn toàn bỏ qua tệp định tuyến gói cha nếu tên giống hệt nhau.

EDIT: Trong nhiều trường hợp nó cũng thực tế nhập khẩu đường bó mẹ vào tập tin định tuyến bó con như thế này:

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

Điều này có vẻ là cách dễ nhất imho, đường dẫn tuyệt đối hoặc tương đối, như được mô tả bên dưới không làm việc với tôi – ivoba

+2

Khi sử dụng gói thừa kế, Symfony ghi đè bất kỳ tệp nào có cùng tên (cho dù đó là mẫu hay tệp cấu hình). – wdev

+0

Đây là cách tôi cũng đã giải quyết nó, với một chút trợ giúp từ FOSUserBundle –

2

Các tài liệu chính thức cho biết rằng bạn sẽ chỉ cần sao chép tập tin định tuyến mẹ để bó con bạn :

Cách dễ nhất để "ghi đè" định tuyến của gói là không bao giờ nhập nó. Thay vì nhập định tuyến của nhóm bên thứ ba, chỉ cần sao chép tệp định tuyến đó vào ứng dụng của bạn, sửa đổi và nhập tệp đó thay thế.

Ngoài ra, bạn không thể bao gồm tệp định tuyến gói của cha mẹ sử dụng tên biểu tượng "@ParentBundle" vì tên này được giải quyết thành "@ChildBundle".

Nếu bạn thực sự muốn bao gồm tệp tuyến đường mẹ, thì bạn phải sử dụng đường dẫn tuyệt đối tới tệp đó hoặc đường dẫn tương đối so với thư mục hiện tại, tức là:

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

hoặc

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

workaround khác là liên kết mềm tập tin định tuyến cha mẹ của bạn vào bó con quý vị và bao gồm nó với con đường ngắn hơn, ví dụ:

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

và sau đó

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

P.S. Tôi hy vọng họ sẽ tìm thấy một số cách tốt hơn và ít xấu xí hơn để ghi đè và mở rộng định tuyến từ gói gốc, nhưng bây giờ chúng ta phải có một số cách giải quyết xấu xí đó.

+0

Gotta nói, mặc dù bạn nói những điều này là xấu, nhưng liên kết tượng trưng gần như quá xấu để đề cập đến. – mattalxndr

Các vấn đề liên quan