I’ve posted this in the Installation & Setup forum, but after some thought that might not be the correct place for it! So I’m sorry for the duplication.
I’d basically like to create a multi-level structure within Yii, to allow long URLs like ‘/page1/page2/page3/page4’. I’ve come up with a solution, but I’m sure there’s a better way of doing it. Please allow me to explain the setup.
I have a default install of Yii running, using the yiic webapp command. The usual URLs work, like ‘http://localhost/site’, ‘http://localhost/site/login’ etc, which are all run from the same default ‘SiteController’.
I’ve created a new controller called ‘TestController’, and placed it under ‘/protected/controllers’ and when I visit the URL of ‘http://localhost/test’ it works as you might expect.
But here’s what I’d LIKE to do:
I’d like to create a directory structure like this, accessible using URLs that correspond to the Controller name:
/protected/controllers SiteController.php /site TestController.php < http://localhost/site/test NewsController.php < http://localhost/site/news /news ContactController.php < http://localhost/site/news/contact EventsController.php < http://localhost/site/events /events ArchiveController.php < http://localhost/site/events/archive
I’ve tried creating a ‘/protected/controllers/site’ directory and placing ‘TestController’ in it, but I get the error:
The system is unable to find the requested action "test".
This is because Yii is running the ‘SiteController’ (because the URL is ‘/site/test’) and looking for an Action called ‘test’.
But I don’t want Yii to look for an action of ‘SiteController’, I want Yii to look for a Controller called ‘TestController’ and run that instead of ‘SiteController’ to be it’s own self-contained Controller that merely sits underneath the ‘site’ directory.
Now, I’ve managed to come up with a solution, but it’s not ideal. I’ve set the directory structure up like so:
/protected/controllers SiteController.php /_site TestController.php < http://localhost/site/test NewsController.php < http://localhost/site/news /_news ContactController.php < http://localhost/site/news/contact EventsController.php < http://localhost/site/events /_events ArchiveController.php < http://localhost/site/events/archive
And I’ve added rules to the urlManager, like so:
'urlManager'=>array( 'urlFormat'=>'path', 'showScriptName'=>false, 'rules'=>array( '/site/<controller:\w+>'=>'/_site/<controller>', '/site/news/controller:\w+>'=>'/_site/_news/<controller>', '/site/events/controller:\w+>'=>'/_site/_events/<controller>', '<controller:\w+>'=>'<controller>', ),
So the URL manager takes care of the URLs for me, but if the site gets big it may become cumbersome to manage - but it allows me to drill down as far as I need to. Maybe there’s a way I can attach a new behavior to a piece of code that, if it fails to find an action, it looks for a controller at that level instead?
Is there a better way of doing this?
Thanks in advance.