views:

600

answers:

3

Using cakePHP my goal is to combine the index view of two or more controllers in one layout page.

Example: I have controllers for: news, events, links. I want to show the last five entries from each table in one layout page. Also, when one of the links from the views is selected it should take the user to the respective view for that record.

I have read through the books section on views but don't see how making a view into an element would accomplish this.

What confuses me is how to combine from three separate controller/views into one layout?

Thanks

+4  A: 

First I would say that views and controllers are not necessarily tied together -- Cake will implicitly add the view specified by the file heirarchy / naming convention, but this doesn't necessarily have to be the case. So try to think of the views as decoupled from the controller (which is one of the main purposes for using the MVC architecture).

Assuming your three views (A,B,C) are exactly how you want them copied, put them into an element (which is just a view file located in the special APP/views/elements/ directory). Now you can use them in either layouts or other views, just by making a call to $this->element( 'elementName', array( 'options' ) ).

Basically, just abstract the code you want to display into elements, then insert those elements into the desired layouts.

Travis Leleu
+1  A: 

You can set up your controller to use the RequestHandler and then make your view elements capable of fetching their own data from separate controllers in your application.

This link explains it better than I can http://bakery.cakephp.org/articles/view/creating-reusable-elements-with-requestaction

One thing to keep in mind is that the controller actions you are calling should account for caching their own data so you don't do unnecessary database queries.

Abba Bryant
nice solution; elegant and efficient.
Paul
+1  A: 

Create methods in your News, Event and Link models for fetching the last 5 records. Then in your controller either include the models in the Controller::uses property, or in the action use ClassRegistry::init() to get access to the model, e.g.

function my_action() {
  $news = ClassRegistry::init('News')->getRecent();
  $events = ClassRegistry::init('Event')->getRecent();
  $links = ClassRegistry::init('Link')->getRecent();
  $this->set(compact('news', 'events', 'links'));
}

You can then call these model methods from any controller action, keeping your application DRY.

In your my_action.ctp view, and indeed many other views, just render the elements e.g.

// my_action.ctp
<?php
echo $this->element('recent_news');
echo $this->element('recent_events');
echo $this->element('recent_links');
?>

Your elements can then just iterate over the $news (or whatever) variable displaying the items with links to the 'view' actions in their respective controllers.

Just because a controller matches a model, doesn't mean you can't use other models in it.

neilcrookes