Hello all, I’m sorry if this has been posted before but I still couldn’t figure this one out yet. If I want to have http://localhost/tools/mytool, it’s as simple as created a ToolsController and actionMytool declared. However, if I want to have 2 levels of controller, how do I get around it? Eg: http://localhost/tools/subtools/mytool/. Thanks in advance ![]()
Use module-controller structure
or define rules for urlManager in your config/main.php to map sub-action to another action (without sub),
or use control as action provider and provide array() with params in actions() method of controller
Maybe my solution is not in the spirit of Yii, but I will just create Tools folder inside Controllers folder and put SubtoolsController.php inside that.
I’m afraid that will not work.
I tried this on my local machine, and after that uploaded to linux host, and it worked like a charm ![]()
I’m a Yii noob, and my approach can be completely wrong, so would you be kind and try to explain me why this won’t work? Is there any consequences that I’m not aware off?
I uploaded this experiment here: http://devel.2klika.net/play/tools/subtools/mytool
this is code for SubtoolsController.php :
<?php
class SubtoolsController extends CController {
public function actionMyTool() {
$this->render('mytools');
}
}
Output of this view is generated through this code in protected/views/tools/subtools/mytools.php
<?php $this->pageTitle = 'MyTools'; ?>
View file: <?php echo __FILE__; ?><br />
Controller file: <?php echo Yii::app()->controllerPath.DIRECTORY_SEPARATOR.$this->uniqueId.'.php'; ?><br />
And this is urlManager part in config/main.php
// uncomment the following to enable URLs in path-format
'urlManager'=>array(
'urlFormat'=>'path',
'showScriptName'=>false,
'caseSensitive'=>false,
/*
'rules'=>array(
'<controller:\w+>/<id:\d+>'=>'<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
),
*/
),
I also have .htaccess file in root of my application with Rewrite rules inside
Options +FollowSymLinks
IndexIgnore */*
RewriteEngine on
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php
This is standard setup for path enabled urls.
Attached image displays both paths of my controller and view file (this is on my local windows based machine, not linux where I uploaded this experiment):

Have a nice day.
P.S.
I almost forgot this (directory structure as outputed by tree command on windows, irrelevant stuff stripped out):
+---controllers
| | SiteController.php
| |
| \---tools
| SubtoolsController.php
|
\---views
|
\---tools
\---subtools
mytools.php
Please pardon me. The only adverse side effect i can foresee is a case where you might have a module with the same name as your sub folder, though i doubt you’d want to do that.
Thank you for your answer.
I did try it with the subfolder but I couldn’t control much of it. I’ll try your new solution (static routing in config). Seems to be good enough for a small scale application for now. Again, thanks a lot all ![]()
p/s: Can someone explain a bit more on module-controller structure. That might be another nice approach.
Module-controller structure is described here.
In a few words, you create a folder named modules in your application, and then a folder named as your first level link (subtool in your example).
In this folder you create the structure (folders controllers, models and views) and then in the folder subtool/controllers you can create myToolController.php, that will be invoked at the request of subtool/mytool.
for make it work you have to edit config.php and add modules->array(‘subtool’).
Maybe this explaination is a bit confuse, but is difficoult to summarize in a few words how to do it.
Try reading the guide and will be all clear.