32

Is there a way to render a controller to a different view then normal? I'm trying to pass some data from the controller to a non-default view. Meaning my controller is called:

class StocksRealtimeController extends AppController {
    var $uses               = 'StockRealtime';
    function index(){
        $action = '/TestView';
        $this->set('stocksRT', $this->StockRealtime->find('all'));
        //$this -> viewPath = 'Pages';
        $this -> render('/TestView/index');
    }
}

... and My view is in views->TestView->index.ctp

Another question I have is, how to pass that value to a PHP and not a ctp file outside of the CakePHP framework?

I have tried everything from here with no luck.

ᴍᴇʜᴏᴠ
  • 4,804
  • 4
  • 44
  • 57
devmonster
  • 1,729
  • 8
  • 24
  • 48

7 Answers7

63

The right way:

$this -> render('TestView/index');

As the answer above mentions, you can use $this -> set to pass a variable to the View.

However, if that doesn't give you what you want. I'm guessing that you also want the action to display another layout (non-default layout). You can try doing $this -> layout = 'layoutname'; (Layouts are in the layout folder, default on is default.ctp).

Note: CakePHP's controller isn't designed to pass data to a non-view file (like .php). CakePHP's views should be ending with .ctp.

Marty
  • 146
  • 1
  • 13
40pro
  • 1,283
  • 2
  • 15
  • 23
  • maybe I'm late.. but if you set variable "*_for_layout" will be available in layout too. – kappa Oct 21 '13 at 13:08
  • 2
    For me, I needed to put a / in front of the path (e.g. `/TestView/index`). – Kevin Jurkowski Mar 17 '14 at 18:11
  • 2
    A warning. Calling `$this->render()` before viewVars are set will make them unavailable in your view. –  May 22 '14 at 09:08
  • 2
    The `render()` method will stop the controller execution and whatever code is after that line will be omitted. Setting the `view` property instead is a better idea, the answer from @Sabin Neagu should be accepted. – ᴍᴇʜᴏᴠ Jul 01 '15 at 18:27
  • As of date, [Cake v2.x](https://book.cakephp.org/2.0/en/controllers.html#Controller::render) and [Cake v3.x](https://book.cakephp.org/3.0/en/controllers.html#Cake\Controller\Controller::render) will need a leading `/` if you want to render a view from within `/app/View` and no leading `/` if the view to be rendered is from a plugin. Linked to appropriate documentation. – Fr0zenFyr Oct 12 '18 at 08:21
  • @KevinJurkowski Forward slah `"/"` is what i am looking for .! Thanks man :) – TarangP Feb 11 '21 at 12:58
47

I would rather use:

$this->view = 'file';

because any $this->set('var', $val) you'll have after $this->render('file') will not reach your view.

In CakePHP 3.x use:

$this->viewBuilder()->template('file');

Deprecated in CakePHP 3.7. Use this instead (as Kuldeep Choudhary suggested in comments)

ViewBuilder::setTemplate('file');
Sabin Neagu
  • 712
  • 7
  • 15
  • 1
    No wonder! I was so sure I was setting the variable correctly, but the view pops a notice that 'it' is not set. Thanks for that tip! – Marky Jul 12 '14 at 08:43
  • 6
    This should be the recommended answer; it fits best with the cake paradigm. – webkraller Mar 03 '15 at 20:06
  • 2
    Agreed, looks more flexible to me. This should be the accepted answer. – ᴍᴇʜᴏᴠ Jul 01 '15 at 18:24
  • 2
    Now in CakePHP 3.7 - $this->viewBuilder()->setTemplate('file'); - Warning (512): ViewBuilder::template() is deprecated. Use ViewBuilder::setTemplate() or ViewBuilder::getTemplate() instead – Kuldeep Choudhary May 01 '19 at 13:34
11

Try to put the name of the view without .ctp extension.

$this->render('file');
3
class StocksRealtimeController extends AppController
{
   var $uses = 'StockRealtime';

   function index( )
   {
     $this->layout     = NULL;
     $this->autoRender = false;

     $this->set('stocksRT', $this->StockRealtime->find('all'));

     return $this -> render('/TestView/index');
     /*
        $this -> render('/TestView/index');
        Here 'TestView' must be a Folder named same as "public $name" variable value        
        in Controller and an "index.ctp" must be situated under TestView Folder.
       'index'
     */
   }
}

Give it a try, return 'KEYWORD' must be there to render view page successfully. Sorry about 2nd question as i didn't get it. According to CakePHP, variable [stocksTR] which is set using $this -> set( ) , also will be available at manually render view page [ 'index.ctp' ].

mistertandon
  • 1,424
  • 14
  • 15
1
 $this->view  = '/TestView/index';
 $this->set('stocksRT', $this->StockRealtime->find('all'));
gdm
  • 7,647
  • 3
  • 41
  • 71
0
class StocksRealtimeController extends AppController {
var $uses               = 'StockRealtime';

    function index(){

       $this->layout = NULL;
       $this->autoRender = false;

       $this->set('stocksRT', $this->StockRealtime->find('all'));

       $this -> render(`/TestView/index`);

    }
}
kamleshpal
  • 13
  • 4
chetanspeed511987
  • 1,995
  • 2
  • 22
  • 34
  • I did what you suggested , and still, the page http://localhost/cakephp/TestView, looks for the testcontroller => "Error: TestViewController could not be found." – devmonster Jul 30 '12 at 05:40
0
public function admin_index() { 

    $this->layout = 'admin/table';

    $action = '/Vendors';

    $this->Prg->commonProcess('Vendor');

    $this->paginate = array('conditions' => array($this->Vendor->parseCriteria($this->passedArgs)), 'order' => 'Vendor.created_on DESC', 'limit' => 15);

    $this->set('vendor', $this->paginate('Vendor'));

    $this->render('/vendors/admin_items');
}
John Hascall
  • 9,176
  • 6
  • 48
  • 72
Ajay Kori
  • 11
  • 5