Page 1 of 2
Templates which "Pull" model data
Posted: Fri Feb 15, 2008 4:57 pm
by Chris Corbyn
So I always see people using a "push" style approach to getting model data into the view... but does anyone have an example of a "pull" style approach where the view gets it own model? I don't recall ever seeing it in PHP, though I have seen it using JSP tag libraries.
Re: Templates which "Pull" model data
Posted: Fri Feb 15, 2008 7:50 pm
by Christopher
This is something I have done for a very long time, and in some ways I think it is better than having the Controller involved. The reason is that I find that Controllers can quickly lapse into Transaction Scripts when both Model and View are dealt with, because it is easy to just at one little workaround, and then two, and then ... well you know ...
But I have been criticized in MVC discussions for thinking Model Pull is ok.
It the current version of the Skeleton Framework we provide identical loading of Models in both the Controller and View. I have found it pretty handy and it makes some things cleaner. I do think Model Push still has it place because you want less coupling in some Views. And those are the deciding factors: coupling and dependency.
Re: Templates which "Pull" model data
Posted: Fri Feb 15, 2008 7:58 pm
by Chris Corbyn
I always thought model-pull was the right way to go, albeit the most difficult way to implement... which is why I've always just made the trade-off of having my controller pass data to the view. The reason I asked this question is because every time I want to display a little more on a page than I'm already displaying I feel a bit odd editing the controller just to give that data to the view. The model is already there... the controller shouldn't really need to figure out if the view needs it or not.
Where is your skeleton framework again sorry? I remember you posting a link to it somewhere but I forget now

If it was never public just drop me a PM

Re: Templates which "Pull" model data
Posted: Sat Feb 16, 2008 4:54 am
by blueyon
The problem I have found when using objects inside the view is that it makes ther views less reusable.
Say I have a list view that is used by a number of different controllers. Different controllers have different column names so If I put the column names into a array and push the data into the view I can reuse the same view with other controllers. If I pull the data in I'm going to have to hard code each column into its own sperate view.
Your sacrificing flexability for speed.
Skeleton Framework:
http://ap3.sourceforge.net/downloads/
Re: Templates which "Pull" model data
Posted: Sat Feb 16, 2008 9:45 am
by Christopher
blueyon wrote:The problem I have found when using objects inside the view is that it makes ther views less reusable.
Technically using a Model inside a View should not make it less reusable because typically you will have a many Views to one Model relationship. It is the rarer case of when you use the same View for different Models that you must use the Controller.
So the question is, what does the Controller give to the View -- a Model or the ID for the model to use? It may seem a pure vs practical decision, but as Chris says ... it seems odd to edit the Controller to change the View.
Re: Templates which "Pull" model data
Posted: Sun Feb 17, 2008 5:01 pm
by blueyon
I think your right about the pull method.
I'm working on an updated controller now. This page controller can pull the in objects straght into the view:
Code: Select all
<?php
class Controller {
protected $data = array();
protected $locator;
public function __construct(&$locator) {
$this->locator =& $locator;
}
public function __get($key) {
return $this->locator->get($key);
}
public function __set($key, &$value) {
$this->locator->set($key, $value);
}
public function __call($method, $args) {
return call_user_func_array(array($this->locator, $method), $args);
}
protected function forward($controller, $action) {
return new Action($controller, $action, array_slice(func_get_args(), 2));
}
protected function redirect($url) {
header('Loaction: ' . $url);
exit();
}
protected function render($filename) {
echo $this->fetch($filename);
}
protected function fetch($filename) {
$file = DIR_VIEW . 'template/' . $filename . '.tpl';
if (file_exists($file)) {
extract($this->data);
ob_start();
include($file);
$content = ob_get_contents();
ob_end_clean();
return $content;
} else {
exit('Error: Could not load template ' . $file . '!');
}
}
protected function getChild($child) {
$file = DIR_CONTROLLER . $child . '.php';
$class = preg_replace('/[^a-zA-Z0-9]/', '', 'Controller' . $child);
if (file_exists($file)) {
include_once($file);
$controller = new $class($this->locator);
$controller->execute();
} else {
exit('Error: Could not load controller ' . $child . '!');
}
}
}
?>
The View:
Code: Select all
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<?php $this->getChild('module/head'); ?>
</head>
<body>
<div id="container">
<div id="header">
<?php $this->getChild('module/header'); ?>
</div>
<div id="column">
<?php $this->getChild('module/column'); ?>
</div>
<div id="content">
<h1><?php echo $heading_title; ?></h1>
<?php echo $text_greeting; ?>
<h1><?php echo $text_latest; ?></h1>
<?php foreach ($products as $product) { ?>
<div class="products"><a href="<?php echo $product['href']; ?>"><img src="<?php echo $product['thumb']; ?>" title="<?php echo $product['name']; ?>" alt="<?php echo $product['name']; ?>" /></a><br />
<b><a href="<?php echo $product['href']; ?>"><?php echo $product['name']; ?></a></b><br />
<?php echo $product['price']; ?></div>
<?php } ?>
</div>
<div id="footer">
<?php $this->getChild('module/footer'); ?>
</div>
</div>
</body>
</html>
Re: Templates which "Pull" model data
Posted: Sun Feb 17, 2008 11:05 pm
by Chris Corbyn
That's actually "push". i.e. the controller is "pushing" data into the view. In a "model-pull" scenario, your controller doesn't do that... instead the view looks up (requests) the model data it needs.
JSP tag libraries typically do this by fetching JavaBeans from a store somewhere (such as via Hibernate).
Re: Templates which "Pull" model data
Posted: Sun Feb 17, 2008 11:24 pm
by Christopher
I looked at the code a couple times and am not sure it is push or pull. The View and Controller are combined -- the View is calling Controller methods with $this. You can't do push/pull without the VC separation.
Re: Templates which "Pull" model data
Posted: Mon Feb 18, 2008 1:49 am
by Mordred
I do something similar in my not-exactly-MVC framework - a template can be given data, or can be given an object or array from which to pull data. I think in MVC terminology it would be equvalent of having the controller say to the view: look, here's the model, get whatever you want from it. Thus both ways to look at the situation become functionally equivalent - the view is pulling what it needs == the controller pushes from the view to model, but without an explicit detailed list of which properties to push.
Re: Templates which "Pull" model data
Posted: Mon Feb 18, 2008 3:54 am
by blueyon
I think this was VC separation.
I don't want to add a third layer for the template.
With the controller and view combined the view or template can have direct access to the objects within the controller.
Re: Templates which "Pull" model data
Posted: Mon Feb 18, 2008 5:20 pm
by blueyon
Have you not noticed there are alot of frameworks out there using a render method in the page controller.
Smalltalk-80 uses the 1:1 view:controller as do many frameworks.
Re: Templates which "Pull" model data
Posted: Mon Feb 18, 2008 5:33 pm
by Christopher
I understand that many Smalltalk programmers 20 years ago used tightly coupled View/Controller pairs. And I think that that design is sometimes appropriate today. I also think one Controller, many Views is also appropriate -- especially when using modern Action Controllers.
But back to the OP, the whole point of Pull vs Push is whether the View gets the Model or the Controller gives the View the Model. If you combine the View and Controller, the question is rather moot.
Re: Templates which "Pull" model data
Posted: Mon Feb 18, 2008 8:19 pm
by Jenk
blueyon wrote:Have you not noticed there are alot of frameworks out there using a render method in the page controller.
Smalltalk-80 uses the 1:1 view:controller as do many frameworks.
Depends on the framework within..
Seaside uses WATask as a primitive controller, and WAComponent to render the view. Although you can use WAComponent as controllers, it is heavily discouraged and you also have limited "controller" functionality compared to WATask. No #isolate: for example, and you're already in the rendering phase when using WAComponent, making bloat easy to gain.
Re: Templates which "Pull" model data
Posted: Tue Feb 19, 2008 6:20 am
by blueyon
A brief list of all the frameworks using the render method in a controller.
Zend
Symphony
Akelos
I think ruby on rails.
The only way I can think of to have a render method in the page controller is to have the controller have a view combined. THis method does not cause bloat.
It seems like there is an extra layer being added when you are doing it arborints way. You now have Model-View-Controller-Template.
1. In arborints examples it means you are attaching all the different components of the page on every single controller.
2. Its no longer leaving it upto the view to decided which sub controllers are begin used.
3. The sub parts of the page might have there own functionality such as a search box so a controller should be required.
4. You are turning the view layer into a controller by adding functionality before displaying things.
Re: Templates which "Pull" model data
Posted: Tue Feb 19, 2008 6:30 am
by Chris Corbyn
IMHO, "template" is not separate from the view. It's part of the view (and in some cases the only "part" of the view).
I tend to (when I'm using my own framework-ish code) use a "View" class which "loads" a template. The View class is nothing more than a container for data (i.e. "pushed" into it from the controller in my case), and a collection of View helpers (*sigh* using Mixins).