Hi,
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.