Optional Prefix part in Route - symfony

I'm trying to create a rather complex-route schema and I'm stuck.
Routes that I wan't to match
/books indexAction
/books/show showAction
/books/authorname indexAction
/books/authorname/show showAction
Current Setup
Routing.yml
actions:
resource: routing/actions.yml
prefix: /books/{authorname}
requirements:
authorname: ".*"
defaults:
authorname: ''
routing/actions.yml
books_index:
path: ""
defaults: { _controller:bookController:indexAction }
books_show:
path: "/show"
defaults: { _controller:bookController:showAction }
This Setup currently matches only:
/books/ indexAction
/books/show showAction
/books/authorname indexAction
/books/authorname/show showAction
but not
/books
The reasons why I split those routes into two files is that in reality the actions contain much more routes, also there is other routing-categories then the actions.
I know I could define the /books route manually without a prefix but I want to avoid this as this schema will be used for many different modules.

You need a /book prefix in any case.
One solution is to define separate entries in your routing.yml for that. One with /books prefix and the second with /books/{authorname}.
index:
resource: routing/actions.yml
prefix: /books
show:
resource: routing/actions.yml
prefix: /books/{authorname}
It's not so elegant, but in this case you can get rid of extra requirements section.
Hope this helps!

Related

In Symfony is it possible to if a route matched, forward to other route

I have two routes in two separated bundles: bundleA_route, bundleB_route. In my /app/config/routing.yml I load them as resources like:
bundle_a_routing:
resource: "#SomeABundle/Resources/config/routing.yml"
prefix: /
bundle_b_routing:
resource: "#SomeBBundle/Resources/config/routing.yml"
prefix: /
In most cases this sequence is required, first of all try to match on routes in bundle_a_routing, and then try to match on routes in bundle_b_routing, but in only one case I want to make an exception, I want a single route defined in bundle_b_routing to be matched before the more "concessive" route defined in bundle_a_routing:
route_in_bundle_a:
path: /admin/{path}
defaults: { _controller: SomeABundle:SomeCtrl:someAction }
methods: [GET]
requirements:
path: ^(.*)$
route_in_bundle_b:
path: /admin/download/{formId}/{fileName}
defaults: { _controller: SomeBBundle:SomeOtherCtrl:someOtherAction }
methods: [GET]
requirements:
formId: \d+
fileName: ^([a-fA-F0-9]{32}(?:\.[a-zA-Z0-9]{1,222})?)$
Now the request URI "http://servername/web/app_dev.php/admin/download/12/23d2fff7f606e93acac9ede5b4e2b394.png" matches the first, but I want to match the second...what is the official scenario in cases like this?
You should change the order in which you are importing routes, so the route http://servername/web/app_dev.php/admin/download/12/23d2fff7f606e93acac9ede5b4e2b394.png will trigger the route_in_bundle_b first and the routes that doesn't have the download segment will not trigger it and will trigger the route_in_bundle_a rule.

Symfony : ignore some route

I want use Symfony4 with Vuejs app in the same corner of my server (on the same domaine)
But Sf routing is master and (than VueJs router) generate some 404
mode: 'history',
using the history mode.
Thanks for your tricks ;) .
approach number 1:
routing configuration to have a "jolly" route:
this route MUST be latest to match
jolly_all_in:
path: '/{jolly}'
controller: 'App\Controller\JollyController::allInPrintVueInit'
requirements:
jolly: '.*'
or in this case all your vue route MUST has a prefix "your-vue-route-prefix"
jolly_all_in_with_prefix:
path: '/your-vue-route-prefix/{jolly}'
controller: 'App\Controller\JollyController::allInPrintVueInit'
requirements:
jolly: '.*'
with this approach you must manage your 404 from JS.
approach number 2:
you MUST map all your JS route to symfony route.
example
user_list:
path: '/user'
controller: 'App\Controller\VueController::printVueInit'
user_get:
path: '/user/{id}'
controller: 'App\Controller\VueController::printVueInit'
requirements:
id: '\d+'
[...]:
path: '/.../.../...'
controller: 'App\Controller\VueController::printVueInit'

Define route without ending slash when importing route in Symfony 2.5?

In file: HardCoreMore/HRAPIBundle/Resources/config/routing.yml
I have imported route like this:
hr_api_company:
resource: "#HRAPIBundle/Resources/config/routing/company.yml"
prefix: /company
And in file: HardCoreMore/HRAPIBundle/Resources/config/routing/company.yml
I have defined route for creating company like this:
hardcoremore_hr_api_company_create:
pattern: /
defaults: { _controller: HRAPIBundle:Company:create }
methods: [POST]
Now the route is matched with following url:
POST company/
but it is not matched when I called it with:
POST company
How can I define route without ending slash when importing route and prefixing it?
this is not possible, see : https://github.com/symfony/symfony/issues/4322
I hope this has helped

Symfony2 i18n routing - defining an array of requirements

Is it possible to define an array of locales used in Symfony2 routing rules, so that I won't have to repeat it over and over in every route and alter it for each route separately in case I change the supported languages list?
I know it's very easy to do a quick search & replace in routing.yml, but the issue's scope could be easily expanded so that it provokes a question like this: is it possible to provide this locale array externally (i.e. to have it read from a database)?
For clarification - here is an example of what I have now:
page_show:
pattern: /{_locale}/page/{slug}
defaults: { _controller: myCompanymyBundle:Cms:pageShow }
requirements:
_locale: en|pl
slug: "[^,]+"
news_archive:
pattern: /{_locale}/news/archive
defaults: { _controller: myCompanymyBundle:Cms:newsArchive }
requirements:
_locale: en|pl
And here is an example of what I'd like to have:
page_show:
pattern: /{_locale}/page/{slug}
defaults: { _controller: myCompanymyBundle:Cms:pageShow }
requirements:
_locale: languages
slug: "[^,]+"
news_archive:
pattern: /{_locale}/news/archive
defaults: { _controller: myCompanymyBundle:Cms:newsArchive }
requirements:
_locale: languages
Where languages is an array, be it a YAML array or a PHP array provided externally; it's not really substantial.
This could be very helpful to further ease the configuration of the application I'm writing. I'd like to extract as much configuration as possible into the config.yml file. So that if I decide that, for instance, I want to add a new language quickly and I already support it in the business logic and templating layers, I just have to modify the languages array in config.yml and voila, it's done.
Thats something that bugs me every time. The only thing I could offer is to put your requirement params into app/config/parameters.yml
# src/App/Resources/config/routing.yml
sport:
pattern: /{_locale}/{sport}
defaults: { _controller: App:Vote:vote }
requirements: { _locale: %routing_locales%, sport: %routing_sports% }
# app/config/parameters.yml
parameters:
# routing requirement regex
routing_sports: 'hockey|football' # available sports so far
routing_locales: 'de|fr' # available locales so far

Symfony2 router - how to call annotation route

Simple case. In my all app I'm using Route annotation driver, defined in routing.yml as follows:
MyBundle:
resource: "#MyBundle/Controller/"
type: annotation
prefix: /someprefix
Some action in MyBundle's Ctrl controller looks like:
#Route("/{page}/{status}", name="default_action", defaults={"page" = 1, "status" = "ok"}, requirements={"page" = "\d+"})
public function defaultAction($page, $status) {...}
Now I want to make this action - default action when visiting my web page. I cannot use just #Route("/") because I'm prefixed. So I'm adding to routing.yml:
_welcome:
pattern: /
defaults: { _controller: MyBundle:Ctrl:default }
And there is where problem starts - Symfony2 is calling default controllers action not from annotation but just from action and I get error:
Controller "...:defaultAction()" requires that you provide a value for the "$page" argument (because there is no default value or because there is a non optional argument after this one).
So simply Symfony2 is not obtaining default values from #Route annotation.
Question is: how to call route for _welcome that is aware of #Route?
You've missed defaults in yml settings, should look like this:
_welcome:
pattern: /
defaults: { _controller: MyBundle:Ctrl:default, page: 1, status: ok }

Resources