Symfony2: Can bundle routes be namespaced? - symfony

I have a MagazineBundle which in one of its Twig templates has path('portfolio'), the root of a different bundle that has been prefixed.
# app/config/routing.yml
LameMagazineBundle:
resource: "#LameMagazineBundle/Resources/config/routing.yml"
prefix: /
LamePortfolioBundle:
resource: "#LamePortfolioBundle/Resources/config/routing.yml"
prefix: /portfolio
and
# src/Lame/PortfolioBundle/Resources/config/routing.yml
portfolio:
pattern: /
defaults: { _controller: LamePortfolioBundle:Default:index }
But if I add a third bundle, possibly one I've downloaded and installed, and that bundle also happened to also have a route named 'portfolio', would I have to renamed the routes or is there a way to namespace them?
An experiment I tried with two matching route names results in the last declared one overriding the first.

It's not built into the routing system. You would have to manually prefix your route names with the bundle or some other namespace.
The FOSRestBundle has route prefixing functionality but I'm not sure how coupled it is or if it's something that could be easily used without all the bundles other features.
http://symfony.com/doc/master/bundles/FOSRestBundle/6-automatic-route-generation_multiple-restful-controllers.html#naming-collisions

Related

routing in symfony 4

I want to routing for my app and api like this:
app:
resource: ../src/Controller
type: annotation
prefix: /
api:
resource: ../src/Controller/Api
type: annotation
prefix: /api
Q1: Where should I write this? in config/routes/annotations.yaml or
config/routes.yaml.
Q2: what is different between this two file and which one is used for?
The file config/routes/annotations.yaml was probably created by a flex when applying annotations recipe. I am not 100% sure, but when you want to delete the annotations bundle it will also remove this file.
But it makes sense to me to put all annotation route imports into config/routes/annotations.yaml file, because they just depend on this package.
Other routes you should put into the config/routes.yaml file.

Add optional _locale to routes

I'd like to prefix all my urls by an optional _locale. BTW, I'm handling fr and en.
The point is, when _locale is given I'll use it thanks to symfony Symfony\Component\HttpKernel\EventListener\LocaleListener::onKernelRequest, if not I'll use the locale saved in the database thanks to my own listener (priority: 15) which runs immediately after the previous one.
What I've tried so far is the following:
app/config/routing.yml
entrypoint:
resource: 'locale_prefixed_routing.yml'
prefix: /{_locale}
And locale_prefixed_routing.yml imports bundles routings.
/fr/url/example works but /url/example does not and returns 404 page.
How do I tell symfony to use the locale in the url, if does not exist use the one in the database?
I suppose your routes are defined like this in your locale_prefixed_routing.yml :
my_route:
path: /
defaults:
Actually routes like /url/example without any locale are not defined in your routing because you ask to prefix all the routes loaded in locale_prefixed_routing.yml by the locale. So it is normal to get an error when requesting such a route without locale.
You can try to make another routing file named non_localized_routing.yml containing the same routes except that you will use specific defaults.
Example :
route_example:
path: /url/example
defaults:
_controller: FrameworkBundle:Redirect:urlRedirect
path: /{_locale}/url/example
permanent: true
Tell me if it permits you to get rid of your problem, I haven't test it yet.
For me it sounds weird to store the locale in the database when the locale is not provided by the user. You can simply add a default one:
framework:
default_locale: en

Symfony2 - integration of ckeditor and sonata media bundle

I am trying to integarte IvoryCKEditor with sonata media bundle. Perpose is to allow image uploads in ckeditor. I tried it using a CoopTilleulsCKEditorSonataMediaBundle but i keep getting an error:
An exception has been thrown during the rendering of a template ("Unable to generate a URL for the named route "admin_sonata_media_media_ckeditor_browser" as such route does not exist.") in "IvoryCKEditorBundle:Form:ckeditor_widget.html.twig".
Thanks :)
You should check your routes with the command:
$ php app/console debug:router | grep ckeditor
Then you have to replace admin_sonata_media_media_ckeditor_browser and admin_sonata_media_media_ckeditor_upload by routes founded with this command, in the config of ivory_ck_editor (maybe in your config.yml or your ivory_ckeditor.yml file)
If you don't have route for ckeditor, I think you should check if you install correctly the bundle.
1) install SonataFormatterBundle 2) add the bundle and its dependencies in AppKernel 3) config files 4) CLEAR CACHE 5) roll
Reason of the issue
This problem arises when trying to integrate CKEditor through the
SonataFormatterBundle without using the SonataAdminBundle.
In fact, the integration proposed by the SonataFormatterBundle is meant to only work for the SonataAdminBundle, and no easy integration for a custom admin bundle is currently available.
Note that this dependency is not specified in the documentation at the moment.
How to solve the problem
Simply install the SonataAdminBundle following this installation process. You do need to configure the bundle entirely as specified in the documentation. To add the routes that were missing, such as admin_sonata_media_media_ckeditor_browser, simply add the following to your config/routes.yml:
# This is your custom admin bundle
admin:
resource: "#AdminBundle/Controller/"
type: annotation
prefix: /admin/
# Import SonataAdminBundle routes
admin_area:
resource: "#SonataAdminBundle/Resources/config/routing/sonata_admin.xml"
prefix: /admin/sonata # put whatever prefix here
_sonata_admin:
resource: .
type: sonata_admin
prefix: /admin
Just to add something.
If you are SURE that you have installed, all dependencies, and set all configs correctly, and still getting this error, then the cause may be that you have defined your 'sonata_media' prefix in routing.yml differently.
You can check all urls in your project in:
app/cache/dev/appDevUrlGenerator.php
In there you will find ALL routes in a variable $declaredRoutes
Afterwards simply put correct route name for browsing.
It will not work without SonataMediaBundle - you will need to install it with SonataFormatterBundle
Sonata become too complicated as for me, so I just use IvoryCKEditorBundle directly

Symfony 2 multiple bundles annotation type routing

I have a Symfony 2.3.1 application with two bundles. Each bundle contains Resources/config/routing.yml configuration file:
mobile:
resource: "#MyMobileBundle/Controller"
type: annotation
and
admin:
resource: "#MyAdminBundle/Controller"
type: annotation
This is app/config/routing.yml:
_mobile:
resource: "#MyMobileBundle/Resources/config/routing.yml"
prefix: /mobile
_admin:
resource: "#MyAdminBundle/Resources/config/routing.yml"
prefix: /admin
And app/config/routing_dev.yml contains:
_main:
resource: routing.yml
The problem is that each time only /admin/... or /mobile/... paths are available. If only one routing resource included in app/config/routing.yml everything works fine. Has anybody had such problem? Is it correct to set prefixes for different bundles this way?
The command php app/console router:debug is the best way to debug routes in Symfony2.
According to the details you provided everything seems to be correct and you are saying that removing one of the route prefix "fixes" your issue.
Visualizing your routes in an array
_mobile: # defines the prefix /mobile
mobile: # key that defines how you include your controller's route
main: /mobile/main # "main" is the route name which is duplicated below
_admin: # defines the prefix /admin
admin: # key that defines how you include your controller's route
main: /admin/main # this route override the original "main" route
In Symfony2 a route isn't defined by the addition of the prefix name and the route name but solely by the route name. If you have two routes named main then Symfony2 will only have reference of one.
In the case above, only /admin/main will be accessible because it overrode /mobile/main.
In short, you can't have two routes with the same route name.
So the best solution to fix the example above is by prefixing the route name with a key (much like namespacing):
_mobile:
mobile:
mobile_main: /mobile/main
_admin:
admin:
admin_main: /admin/main
Now you have two routes named admin_main and mobile_main which don't overlap each other.

Ordering of routes using annotations

The usual solution when you create routes in symfony and you want to have one route like
/{username}
so that it does not conflict with other routes like /login or /info is just to put that route as your last route in your routing.yml file. Since all the other routes take precedence this conflict is avoided. But how can you do this if you define your routes as annotations in your controllers? Is there any way to specify the ordering of this routes in this case?
In the context of a controller, the order of action methods defines the order of routes. In the context of the whole application, you can import each controller explicitly to control the order, for example:
Home:
resource: "\Vendor\Controller\HomeController"
type: annotation
Security:
resource: "\Vendor\Controller\SecurityController"
type: annotation
security.log_out:
pattern: "/logout"
User:
resource: "\Vendor\Controller\UserController"
type: annotation
I can't comment on the answer, so I will leave how I had to write it in Symfony 2.3 to get it to work:
Home:
resource: "#AcmeBundle/Controller/HomeController.php"
prefix: /home #optional
type: annotation
Notice the change of "\" to "/" and using .php at the end of controller name.
You need to overwrite the rule for that route at the end of your routing.yml. You can do this by using the same name for the route as the one that is automatically created by the annotation. You can find the name with the console command:
php app/console debug:router
So in your routing.yml as the last line you will add:
the_name_of_the_route_as_found_with_appconsole_debug_router:
path:/{username}
defaults: { _controller: YourBundle:YourController:the_action_to_use }
By using the same name it is given by default you will override the original. Don't forget other options that might be important. Like a default value or null for {username} or the method.
You could also remove completely the route from the annotation for the controller. It is not required anymore as it is overwritten anyway :)

Resources