Creating CakePHP Dynamic Menus
Prior to this example, we created a Sections Controller and a Tutorials Controller via the Book Titles Tutorial techniques.
The MenuBaker Element
Begin by creating the menu Element template, menubaker.thtml, in the /app/view/elements/ folder. See: Element
<!-- elements::menubaker start --> <ul id="nav"> <li style="width:70px;"> <?php echo $html->link( 'Home', '/' ); ?></li> <?php foreach( $menu as $section ): ?> <li> <?php echo $html->link( $section['Section']['name'], '/#', array( 'onClick' => 'blur();', 'class' => 'mainLink' ) ); ?> <div id="submenu"> <ul> <?php foreach( $section['Tutorial'] as $tutorial ): ?> <?php echo $ajax->linkToRemote($tutorial['name'], array( 'fallback' => '/#aview', 'before'=>'blur();' 'url' => "/tutorials/view/{$tutorial['id']}", 'update' => "subcontent", 'after' => "new Effect.Fade('subcontent');", 'complete' => "new Effect.Appear('subcontent');") ); ?> <?php endforeach; ?> </ul> </div> </li> <?php endforeach; ?> </ul> <!-- elements::menubaker end -->
The Bake Element
Next, write an Element to create a static-menu Layout template file. This is done to decrease page-loading time, rather than load the menu, dynamically, upon every page view.
<?php $filename = '/absolute/path/on/server/app/views/elements/menu.thtml'; $handle = fopen($filename, 'w'); fwrite($handle, $menucode); fclose($handle); ?>
Adding MenuBaker To SectionsController
Add a BakeMenu function to the controller - to call the menu-creation Element.
function bakemenu() { $this->layout = ''; $this->set( 'menu', $this->Section->findAll() ); }
Refresh the view by rendering the bake Element ...
<?php $menucode = $this->renderElement( 'menubaker', array( 'menu' => $menu) ); $this->renderElement( 'bake', array( 'menucode' => $menucode ) ); ?>
Re-baking the menu: Calling the BakeMenu Element
Every time menu content is altered, “re-bake” the menu, using the requestAction function at the end of controller method which modified the data.
$this->requestAction( '/sections/bakemenu/' );
Including The Menu In Your Layout
Finally, echo the dynamically-created menu Element in your layout.
<?php echo $this->renderElement( 'menu' ); ?>