hi, i have a problem in this case i have this structure of directory
-module
--user
---controller
----default
----profile
----country
---view
....
when i try use this url (example) http://localhost/user/profile i get 404
but when i use http://localhost/user/profile/index this work...
this is my urlmanager
'urlManager'=>[
//'urlFormat'=>'path',
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules'=>[
'<module:\w+>/<id:\d+>' => '<module>/default/view',
'<module:\w+>/<action:\w+>' => '<module>/default/<action>',
'<module:\w+>/<controller:\w+>/<id:\d+>' => '<module>/<controller>/view',
'<module:\w+>/<controller:\w+>/<action:\w+>/<id:\d+>' => '<module>/<controller>/<action>',
'<controller:\w+>/<id:\d+>'=>'<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
],
],
'<module:\w+>/<action:\w+>' => '<module>/default/<action>',
If you access as http://localhost/user/profile it will translate as route user/default/profile
that is the problem if i remove the first 2 rules, work perfectly but the default controller in the url say "default"
but the default controller in the url say "default"
so what?
i try find a solution for use subcontrollers in the module
like
http://localhost/module/default/action (<---- remove "default)
http://localhost/module/controller/action (<-- correct)
i try find a solution for this 2 case
in the same module im working the user logic, profile logic,etc
but is bad use http://localhost/user/user/index :S
then http://www.yiiframework.com/forum/ is a good place for you to try
im not registered :s
up to you. but github issue not use for asking
im not sure, because in the documentation never mention how can hide the default controller in the url, but show the secundary controllers :/
default controller in Application. Its only has defaultRoute http://www.yiiframework.com/doc-2.0/yii-base-module.html#$defaultRoute-detail.'<module:\w+>/<action:\w+>' => '<module>/default/<action>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
So, if you have url like http://localhost/xxx/yyy where it will be going?
im trying traslate controllers to module logic, but when hi have multiple controllers in a module is a problem, i need define a default controller and hide this in the url the controllername
http://localhost/module/action <-- in this case the default controller name is hide
http://localhost/module/subcontroller/action <--- in this case i show the controller name
sorry i speak spanish for this i have error translating
i need hide the default because the name module is the same of the name controller
http://localhost/user/user/index .... (module is user, but this have multiple controllers user,profile,etc)
my suggestion is add a option for hide the default controller in this case
@mdmunir i think i solve but i don't like this solution
'rules'=>[
//user
'<module:(user)>/<id:\d+>' => '<module>/default/view',
'<module:(user)>/<action:(index|view|me|delete|create|update|login|logout)>/<id:\d+>' => '<module>/default/<action>',
'<module:(user)>/<action:(index|view|me|delete|create|update|login|logout)>' => '<module>/default/<action>',
//generic module
'<module:\w+>/<controller:\w+>/<id:\d+>' => '<module>/<controller>/view',
'<module:\w+>/<controller:\w+>/<action:\w+>/<id:\d+>' => '<module>/<controller>/<action>',
'<module:\w+>/<controller:\w+>/<action:\w+>'=>'<module>/<controller>/<action>',
//generic default
'<controller:\w+>/<id:\d+>'=>'<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
],
i think the bug is the urlmanager cant detect if the second parameter in the url (http://localhost/module/(controller|action)
if is a controller or if is a action....
@cebe can you see this ?
i think the bug is the urlmanager cant detect if the second parameter in the url
This is not a bug. There are no way to detect it is a controller or action. Its your responsibility as programer to tell the rule if is a controller or action.
FYI, you can change this
'<module:(user)>/<id:\d+>' => '<module>/default/view',
as
'user/<id:\d+>' => 'user/default/view',
Dont missperseption with word module, controller, etc. Use <module> does not mean it will be treated as a module. its a just variable. This 2 rules will do the same
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
'<foo:\w+>/<bar:\w+>'=>'<foo>/<bar>',
@mdmunir that will work, but i think this need more documentation in the website yiiframework :S
Sorry to bump this, but I have a suggestion. I am not sure if it does exist (now) since this is an older post.
When you create a "Module" with Gii, it creates DefaultController with the action of "index" and the view "index".
Logically thinking, we access the site via: /controller/action
In the case of modules, the name of the module is in place of the controller: /module/*
Out of the box, if you just go to /module -> it automatically loads the "index" action and view. So it KNOWS how to find the default controller and index action, even though we didn't specify. So behind the scenes, it's passing the request to the DefaultController. Why does it not pass any other action to the DefaultController too?
In DefaultController I added another action, actionBrowse(). When I go to: /module/browse, one would expect it would run the browse action inside DefaultController. However, it throws a 404. While, /module/default/browse works fine, as expected.
I do not think we should have to set up a rules in the url manager. I prefer to NOT mess with the rules unless I absolutely have to.
Added a note to the guide. hope it's more clear now.
@cebe The note only addresses the default route. What about what @WadeShuler said? I think it makes a lot of sense to be able to automatically pass _all_ module/action routes directly to the default controller, especially in single-controller modules, without having to touch the urlManager.
@vercotux that is not possible, how do you know whether user/index refers to the default action of the index controller, or the index action of the default controller of the user module?
@cebe: By priority, from most significant (module) to least significant (action) "bit" of the route. If the index controller exists in the user module, then user/index goes to the index controller's default action. If the user module has no index controller, then user/index "falls back" to the index action of the default controller.
what is the benefit of this? imo it adds unnecessary complexity, computational and also which needs to be explained in the docs. Why should we do it?
One major benefit is better modularization. Suddenly any controller can become its own module, on the outside indistinguishable from the original, which can be trivially and seamlessly plugged into any application.
if you want to have modularization, use modules.
Huh? I am using modules to have modularization, as is everyone else. You seem to have missed the point completely.
@cebe We are using modules!??!
My point, is Yii should automatically pass the action to the controller, of a module, when it is omitted.
You create a user module and it has DefaultController with action index and test:
/user/default/index <-- full path
/user/index <-- short and still works, as it knows to pass it to DefaultController
/user/test <-- error, it can't find the test action.. but why not? it finds index!!!
One would logically assume that the above would work, because index does work when leaving out the controller. This is the DefaultController, it should be default.
So why does /user/index work but /user/test does not work!? Yii should be smart enough to see that there is no TestController so check DefaultController for the test action.
This would allow you to create 1 Controller and have shorter URLs, without having to do the terrible urlManager routes.
My point is /user/index works and is short for /user/default/index, but /user/test is incapable of being smart enough to find /user/default/test.
@WadeShuler What should show /user/profile if in module user I have action profile in DefaultController and index in ProfileController?
Then it should show index of ProfileController.
This would be most beneficial when you have only one Controller, as it would keep your urls cleaner and shorter. However, DefaultController is misleading, because it doesn't act like a default controller.
In order to take advantage, you would obviously need to pay attention for any name conflicts. I think all actions should be ran to default controller when the route doesn't match a controller. I.e.: true meaning of default.
Then it should show index of ProfileController.
And then if I remove index action from ProfileController URL for profile action in DefaultController will magically change and URL /user/profile will show different content?
If it exists, yeah.
Look, /user/index works automatically with new Gii build. If you add another action to DefaultController, say test, /user/test does not work, and it SHOULD! Because it has been named DefaultController. So if it isn't going to act like a default controller, then it should be renamed to something not as misleading, like MainController.
It wouldn't be hard for it to check if the controller exists, then fall back to DefaultController if it doesn't, and a 404 if it still fails.
This feature should be easy to turn off, and the "default" controller should be able to be changed. Either via in the main config, or overridden like we can with layout.
If it exists, yeah.
This is too much magic - this should not be default behavior. But I think that it's worth to add switch like hideDefultControllerRoute to module which enables such behavior only for this module.
Most helpful comment
This is too much magic - this should not be default behavior. But I think that it's worth to add switch like
hideDefultControllerRouteto module which enables such behavior only for this module.