Sorry about the question title, but I couldn't find a more appropriate way to phrase this.
I am currently building a CakePHP powered website and I'm not quite sure how to approach the following issue. The website looks something like the follwing mockup:
The greyed out areas are part of the layout, because their content does not change between views. In the sidebar, I have a collection of ads who are linked to several models. I need controller logic to determine the picture associated with an ad. Also, the ad list needs to be dynamic. Where should I put the logic for building the sidebar?
I've thought about:
- putting the logic into the
AppController
(beforeFilter
/afterFilter
) - the problem is I can't use the controller logic I need (the other controllers inherit fromAppController
, I'm not sure how to use them there). - making a component - is it okay to build components that rely on controllers?
- replicating the sidebar code in all controllers that ren开发者_运维百科der views - this seems kind of stupid to me.
What is the Cake way for this?
Update
After some reading and experimenting, I've gotten to refactoring most of it.
I obtained the best performance by moving the logic for building my ads in the model (eliminating the component that retrieved the pictures) and not using requestAction
. It's almost three times faster and the code looks much better.
I guess the answer is requestAction
in case the results are cachable:
http://book.cakephp.org/view/434/requestAction
I've done something similar for data-driven navigation. I put my logic in AppController::beforeRender
and haven't had any problems. I'm not sure I understand your concern related to controller inheritance. I retrieve my menus via:
$menus = $this->NavMenuItem->groupByMenu();
$this->set( compact( 'menus' ) );
I then created an element that renders the menu. It's executed by the layout via:
<?php echo $this->element( 'navigation', array( 'id' => 'secondary', 'menu' => $menus['SECONDARY'] ) ) ?>
If that doesn't help, maybe you can further explain your issue with controller inheritance in a comment.
It can be done in this way:
- Create an element that will help in layout of the Ad Block
- Create one or more controller that will generate the data required for rendering of the block
- Use requestAction for getting the data out of the models and into the element.
Check the cake book, there is an example of an element where data from Post Model is used to display top/latest 5 posts. Your requirement, I feel, is very similar to it.
Alex,
you're getting a SQL error because the build() function has to be in the Sidebar model, not controller. Also, you don't necessarily need to use $user = array('Sidebar'); you could calling Sidebar in all of your models with this:
$Sidebar = ClassRegistry::init('Sidebar');
and then $Sidebar->find();
, $Sidebar->build();
etc.
Or, if you only need to call the build() function from the Sidebar model, you could do this:
$sidebar = ClassRegistry::init('Sidebar')->build();
$this->set('sidebar', $sidebar);
Cheers.
精彩评论