3
\$\begingroup\$

This is my first attempt with MVC and I almost get it, but a small thing bothers me.

I have this controller in CodeIgniter:

<?php
class Page extends CI_Controller {

    public function index($page = "home")
    {
            $data['page'] = $page;
            list($data['title']) = array_keys($this->_menu(), $page);
            $data['menuItems'] = $this->_menu();

            $this->load->view('templates/header', $data);
            $this->load->view('templates/menu', $data);
            $this->load->view('pages/'.$page, $data);
            $this->load->view('templates/footer', $data);
    }

    private function _menu()
    {
        static $menuItems = array(
                           "Home page" => "home",
                           "Our history" => "history",
                           "About us" => "about",
                           "Contact page" => "contact"
                       );

        return $menuItems;
    }
}

And here is the menu view:

<?php
$menu = "";
foreach ($menuItems as $menuName => $view) {
    $menu .= '<li';
    if ( $page == $view ) {
        $menu .= ' class="selected">';
        $menu .= '<a href="#">';
    } else {
        $menu .= '><a href="' . $view . '">';
    }
    $menu .= $menuName . '</a></li>' .PHP_EOL ;
}

echo $menu;

Where do the menu items belong in MVC logic? Is it ok to store things like the menu in the Controller or do I have to make a new Model for it like this?

class Menu extends CI_Model {

    public function __construct()
    {
        parent::__construct();
    }

    public function get_menu_items()
    {
        static $menuItems = array(
                           "Home page" => "home",
                           "Our history" => "history",
                           "About us" => "about",
                           "Contact page" => "contact"
                       );

        return $menuItems;  
    }
}              

Then load it from Controller:

public function index($page = "home")
{
    ...
    $this->load->model('Menu');
    $data['menuItems'] = $this->Menu->get_menu_items();

    $this->load->view(...);
    $this->load->view(...);
    $this->load->view(...);
}
\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

This a nice example: it shows how the MVC is just a pattern which should be ajusted to your needs.

  • The menu items you're showing seem very unlikely to change over time. This means you can simply put them in your "templates/menu" view.
  • If they're shared among multiple views, then the controller is OK.
  • If the menu items can change dynamically, then your model can provide a meaningful abstraction over your data, and then it would go into a model.
\$\endgroup\$
6
  • \$\begingroup\$ So if I get the menu elements from database, it should go to model, right ? How can I set page title if I put the array into the view ? list($data['title']) = array_keys($this->_menu(), $page); I cannot acces the menu items from the controller then. Or can I ? \$\endgroup\$
    – kissgyorgy
    Commented Apr 28, 2012 at 13:40
  • \$\begingroup\$ $data['menuItems'] becomes $menuItems in the view. So if you want to use array_keys, simply use array_keys($menuItems, "about") to get "About us". By the way, it would make more sense for "about" to be the key, and "About us" to be the value. You could then write $menuItems["about"]. Why don't you simply use a foreach over $menuItems? \$\endgroup\$ Commented Apr 28, 2012 at 13:47
  • \$\begingroup\$ I want the active page menu item to look different, so I mark the active menu with selected class. In my question I meant that If I put the menu elements array in the view, not the controller, I can't determine what is the actual page title, so it have to reachable from the controller to assign $data['title'] based on which page is active. \$\endgroup\$
    – kissgyorgy
    Commented Apr 28, 2012 at 14:13
  • \$\begingroup\$ Ah! Simply set $data['page'] = $page;? \$\endgroup\$ Commented Apr 28, 2012 at 14:19
  • \$\begingroup\$ I want "About us" to be the page title in the browser tab, not "about". And I cannot if I put the array in the view. \$\endgroup\$
    – kissgyorgy
    Commented Apr 28, 2012 at 14:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.