Packages and rendring view from controller
Permalink 1 user found helpful
I'm trying to render different views from one controller.
My setup:
Controllers:
flash_catalog/controllers/dashboard/flash_catalog/manage_flash
Views:
flash_catalog/single_pages/dashboard/flash_catalog/edit_flash
flash_catalog/single_pages/dashboard/flash_catalog/list_flash
on DashboardFlashCatalogManageFlashController class in edit_flash method
I try to call list_flash view to render like this
$this->render('/flash_catalog/single_pages/dashboard/flash_catalog/edit_flash');
I got only empty page.
I have work around for this creating controller for every view, but is it the right way?
My setup:
Controllers:
flash_catalog/controllers/dashboard/flash_catalog/manage_flash
Views:
flash_catalog/single_pages/dashboard/flash_catalog/edit_flash
flash_catalog/single_pages/dashboard/flash_catalog/list_flash
on DashboardFlashCatalogManageFlashController class in edit_flash method
I try to call list_flash view to render like this
$this->render('/flash_catalog/single_pages/dashboard/flash_catalog/edit_flash');
I got only empty page.
I have work around for this creating controller for every view, but is it the right way?
Hold on a sec -- I think I just figured it out! It's a bit of a hack, but should work.
You want the controller to be here:
flash_catalog/controllers/dashboard/flash_catalog/view.php
and the controller class name should be "DashboardFlashCatalogController"
The views can be here:
flash_catalog/single_pages/dashboard/flash_catalog/edit_flash.php
flash_catalog/single_pages/dashboard/flash_catalog/list_flash.php
But here's the trick:
You want to have one default view template (flash_catalog/single_pages/dashboard/flash_catalog/view.php), and all of the other view files are for specific actions in your controller. This way you only install one single page to the site (at the path "dashboard/flash_catalog") -- if you install more, then the system looks for different controllers (which you don't want -- you want the one controller handling all requests to this section).
And here's the other trick:
At the end of each action method inside your controller file (besides view(), which will work just fine automatically), call $this->render() in the exact right way. For edit_flash, it's this:
and for list_flash, it's this:
Like I said, it's super hacky. Note that you only need to put in this ridiculous render path if you're in a package. If instead you're just putting single_pages and controllers into your site's top-level directories (so not inside the packages directory), you could just pass a path like this to the render() function:
You want the controller to be here:
flash_catalog/controllers/dashboard/flash_catalog/view.php
and the controller class name should be "DashboardFlashCatalogController"
The views can be here:
flash_catalog/single_pages/dashboard/flash_catalog/edit_flash.php
flash_catalog/single_pages/dashboard/flash_catalog/list_flash.php
But here's the trick:
You want to have one default view template (flash_catalog/single_pages/dashboard/flash_catalog/view.php), and all of the other view files are for specific actions in your controller. This way you only install one single page to the site (at the path "dashboard/flash_catalog") -- if you install more, then the system looks for different controllers (which you don't want -- you want the one controller handling all requests to this section).
And here's the other trick:
At the end of each action method inside your controller file (besides view(), which will work just fine automatically), call $this->render() in the exact right way. For edit_flash, it's this:
$this->render('/dashboard/../../../packages/flash_catalog/single_pages/dashboard/flash_catalog/edit_flash');
and for list_flash, it's this:
$this->render('/dashboard/../../../packages/flash_catalog/single_pages/dashboard/flash_catalog/list_flash');
Like I said, it's super hacky. Note that you only need to put in this ridiculous render path if you're in a package. If instead you're just putting single_pages and controllers into your site's top-level directories (so not inside the packages directory), you could just pass a path like this to the render() function:
$this->render('/dashboard/flash_catalog/edit_flash');
A simpler solution is to turn view.php into a dispatcher, and to include in that file just the code to select the view you want, using include(). Here's one of my view.php files:
switch($this->controller->getTask()) {
case 'update':
case 'edit':
include('edit.php');
break;
case 'add':
include('add.php');
break;
default:
include('default.php');
}
switch($this->controller->getTask()) {
case 'update':
case 'edit':
include('edit.php');
break;
case 'add':
include('add.php');
break;
default:
include('default.php');
}
Also note that I fixed this issue in the core code so as of Concrete5.5 you can include different view templates from a single_page controller in a package just like you could before from site-level single_pages. So the OP's original code:
...will work now in 5.5+
$this->render('/path/to/template')
...will work now in 5.5+
Seems that the way to implement different views for the same controller is to put it all in one view file and have a big "if" statement based on $this->controller->getTask() . Very unfortunate if building a system of any complexity (more than 2 pages). I believe this was a design decision to try to keep things simple for the simple cases. Unfortunately it makes the complex things really hard to write cleanly.