ViewModels
ViewModels are optional; if you don't need them, you can use Views.
What is a ViewModel?
A ViewModel is a class that contains the logic that is needed to generate your views. When the controller is done with your user input and is done with whatever actions it needed to take, it turns execution over to the ViewModel to retrieve whatever data is needed for the view. A ViewModel shouldn't do any data manipulation, but can contain Database calls and any other retrieval or preparation operations needed to generate the View's data.
Creating a ViewModel
First we'll create an empty ViewModel in app/classes/view/index.php:
class View_Index extends ViewModel {}
Then you create the view to which this belongs in app/views/index.php:
<h1><?php echo $title; ?></h1>
<ul>
<?php
foreach ($articles as $a)
{
echo '<li>'.$a->title.'</li>';
}
?>
</ul>
On view names: A ViewModel and its view are expected to share the same name. Thus a
ViewModel View_Index expects the view to be in app/views/index.php. And underscores
work here the same as with classes, which means that the view for View_Some_Thing is expected
to be in app/views/some/thing.php.
This default can be overwritten by setting a non-static $_template property in your ViewModel with the
View name (without .php suffix).
And last we'll call the ViewModel from the controller:
ViewModel::factory('Index');
Now we have everything setup there is still no data passed to the view. That still needs to get a $title string and $articles array passed to it. This we do by adding a view() method to the ViewModel which will assign this data:
class View_Index extends ViewModel {
public function view()
{
$this->title = 'Testing this ViewModel thing';
$this->articles = Model_Articles::find('all');
}
}
And you're done.
Passing functions to views
To pass a View specific function from your ViewModel to your View you use Closures:
// In the ViewModel
class View_Index extends ViewModel {
public function view()
{
$this->echo_upper = function($string) { echo strtoupper($string); };
}
}
// Which you can then use in your view:
$echo_upper('this string'); // Outputs: "THIS STRING"