Page 1 of 1

MVC restrictions

Posted: Wed Sep 06, 2006 2:45 am
by jurriemcflurrie
Hey all, I'm busy building a frame (mvc) quite a long time now, and it goes very well. But I wonder how and where I should build some page navigation. Maybe in the layout file? But when I do that, I still need a place for some kind of a submenu.

So I made an object for it, fetching the submenu from the controller:

Code: Select all

class Controller {
	
	var $submenu = array(
		'Ctrl/Add' => 'New item',
		'Ctrl/Index' => 'View index'
	);
	
}
So the menu gets those vars above and it gets the menu itself from a config file (site sections as Home, Images, Contact, etc). I don't like this approach at all.

I have these things all the time (page titles, authorization, I really dunno where to put them exactly). Maybe it's time to learn more about design patterns. Anyway, I'd like to hear your thoughts on this 'problem' and how you'd solve it.

Thanks in advance!

Posted: Wed Sep 06, 2006 12:24 pm
by John Cartwright
The controllers purpose is to sort of the logic of the request, and should never have to deal with page specific variables such as page titles (this belongs in the view). In your case, I would do something like

Code: Select all

class IndexController extends ApplicationController
{
   function IndexAction() 
   {
      $this->view->paintHeader();
   }
}

class IndexView extends ApplicationView
{
   function paintHeader() 
   {
      $this->set('links', $this->model->getNavigationLinks());
   }
}

class IndexModel extends ApplicationModel
{
    function getNavigationLinks() 
    {
       //get links from datasource (config file, db, etc)
    }
}
Maybe I don't understand your issue, does this make things simpler?

Re: MVC restrictions

Posted: Wed Sep 06, 2006 1:14 pm
by Christopher
jurriemcflurrie wrote:I have these things all the time (page titles, authorization, I really dunno where to put them exactly). Maybe it's time to learn more about design patterns. Anyway, I'd like to hear your thoughts on this 'problem' and how you'd solve it.
First, I don't think the all go in the same places.

- For things like page titles and global menus I would recommend creating a Main View outside the controllers. Then have the action controllers create the page specific sub-view and that view can set the global stuff with setContent(), setTitle(), etc. methods in the Main View.

- Authorization (login) is just a single action implementation. However there needs to be Access Control code on several layers of your code -- specifically in the Front Controller / Intercepting Filter and the Action Controller.

Posted: Thu Sep 07, 2006 8:51 am
by jurriemcflurrie
Jcart: Very clear. Thanks!

arborint: The authorization part I understand. About the other, what do u mean with 'creating a Main View outside the contollers'? Could you give an example?

Posted: Thu Sep 07, 2006 4:20 pm
by Christopher
I often use something similar in concept to this:

Code: Select all

class MainVIew {
var $content = '';
var $head = '';
var $bodyattr = '';
var $content = '';

function setTitle($value) {
     $this->title = $value;
}

function addToHead($value) {
     $this->head .= $value;
}

function setBodyAttrubutes($value) {
     $this->bodyattr = $value;
}

function addContent($value) {
     $this->content .= $value;
}

function render() {
     echo "<html>
<head>
<title>{$this->title}</title>
{$this->head}
</head>
<body{$this->bodyattr}>
{$this->content}
</body>
</html>";
}

}
The in your action controller you do:

Code: Select all

$mainview = $registry->get('MainView');
$mainview->setTitle('This Page');
$mainview->addContent($template->render() );
// you can render the main view here or return to and have the main script render or redirect

Posted: Thu Sep 07, 2006 4:33 pm
by Chris Corbyn
arborint wrote:I often use something similar in concept to this
I'm guessing you don't have that echo though?

I prefer to include() a file like this in exactly the same place you call echo in render().

Code: Select all

<html>
<head>
<title><?php echo $this->title; ?></title>
<?php echo $this->head; ?>
</head>
<body <?php echo $this->bodyattr; ?> >
<?php $this->content; ?>
</body>
</html>
EDIT | This also gives you cleaner loop-logic too.

Posted: Thu Sep 07, 2006 7:01 pm
by Christopher
d11wtq wrote:
arborint wrote:I often use something similar in concept to this
I'm guessing you don't have that echo though?
How did you guess? ;)

I would actually probably have the main View contain a template and that's what would render, but I wanted to show the idea. And include would be preferable as well. It is useful in the long run to keep the code scripts and presentation scripts separate.

Posted: Fri Sep 08, 2006 1:19 am
by jurriemcflurrie
Ok I get it!!! Many many thanks!