views:

179

answers:

2

I'm building a small MVC framewrok for a specific PHP application - using Doctrine as ORM. I'd like to know what it would be the best practice to manage the frontend Menu.

My application has 3 menus (horizontal menu, left menu, bottom/footer menu) that can be edited by the site Admin (the menu is stored in a Doctrine NestedSet).

Where should be located the code that calls and renders the Menu? Each controller should be able to call the creation of the menu, according to its requirements (say, for a controller the user do not want the left menu to be displayed).

Locating this function in the Menu Model would be inappropriate I guess...

+1  A: 

The controller should call the code to render the Menu, and use any data from your database within the Model, if needed. Then dispatch the results to your View.

Here is a little breakdown

View

  • Handles contents of the Web page
  • Combination of HTML and PHP in the form of templates.
  • Input and presentation

Model

  • Contains business logic of your application
  • Where all data from your database would reside.

Controller

  • Receives input and requests a response from appropriate Model's.
Anthony Forloney
For instance, the View would call the related Menu HTML template?
Roberto
Yeah, the View would display the HTML template.
Anthony Forloney
A: 

I currently achieve multi-tier menus in my MVC framework (Symfony specifically but this pattern should transfer) by setting the rendering in a separate include (component in Symfony terms) that recursively calls itself to render each tier. The include's controller requests the current tier from the model and then passes it to the view. The include's view renders each returned element and calls the include again to print all child elements if available, passing in the current element's ID to query off of the parent value in the model.

As far as conditioning the display of the menu I would leave that in your top level view since it sounds like it's view-specific.

Model

You should be good with Doctrine's findByX methods here to query for the current tier's items. The field in my schema is called parent so I would use findByParent.

Include's Controller

$items = Doctrine::getTable('TopMenuItems')->findByParent( isset($parent) ? $parent : null) ) // null for initial call to grab top-tier elements, recursion should pass in new parent for children

Include's View

<?php foreach($items as $item) : ?>
  // echo HTML element for nav item
  <?php $parent = $item['parent']; include('top_menu.php'); // call nav again to print this item's children ?>
<?php endforeach; ?>

Main View

<?php if($user->wantsTopMenu()) : ?>
<?php include('top_menu.php'); ?>
<?php endif; ?>

Hope that helps.

Cryo