I'm new here so have been reading a lot of forum posts and doing small experiments. This is about figuring out flexible ways of working with the PW's ways of delivering content. Sometimes having the PW template file echo out stuff from $page is just right but I wanted to figure out an approach that starts with that and adds complexity as needed.
So, here I'll show you the parts of my first working test with MVC, recursive rendering of child pages and a template engine.
The PW template file is used as a simple controller to delegate rendering to a view.
//By default we'll use PW's template as the view name.
$name = $page->template->name;
//Load the view file
require_once '../iop/views/'.$name.'.php';
//Create the view object
$view = new $name($options); //<-- options passed to template are passed to view
//Hook it into the PW template object
$this->addHook('Page::renderView', $view, 'renderView');
//After page does "renderView" output will be in $view->output
$page->renderView();
//spew it out
echo $view->output;
Learned the hook from http://processwire.com/talk/topic/1510-templatedisplay-mode/
The view file:
/*
this is a view file:
$options passed to template are passed to view
$options['params'] would be parameters to use in rendering, such as a different template for rendering as child to another page
*/
require_once $config->paths->root.'/supp/StampTE.php';
class sb3d_mvc_test {
var $templateName = null;
var $output = null;
var $kidOutput = null;
var $options = null;
var $depth = null;
public function __construct($options = null){
$this->options = $options;
$this->templateName = get_class($this); //default is to use same name for all the major parts. No extension.
$this->depth = count($this->options['pageStack']);
}
//Prepares data for the template
public function prepare($page){
$msg = 'The '.$page->name.' page.';
if(!empty($this->depth)) $msg .= ' The pageStack count = '.$this->depth;
return array('msg'=>$msg);
}
//Renders child pages
public function renderKids($page, $params){
$kids = $page->children;
if(!empty($kids)){
$this->kidOutput = array();
foreach($kids as $kid){
$this->kidOutput[] = $kid->render(array('params' => $params));
}
}
}
//This view makes use of the StampTE template engine and makes some content from child pages
public function renderView(HookEvent $event) {
$page = $event->object;
$data = $this->prepare($page);
//Limit how far down rendering goes and set parameters for child page. Maybe use callbacks?
if($this->depth==0){ //not rendering as a child page
$raw = file_get_contents('../iop/templates/'.$this->templateName.'.html');
$params = array('renderMode'=>'Sub'); //child pages use this as template name suffix
$this->renderKids($page, $params);
}
else{ //rendering as a child page
$raw = file_get_contents('../iop/templates/'.$this->templateName.$this->options['params']['renderMode'].'.html');
}
//Now we play with the template engine. This one's interesting in the way it does cut and paste within a template
// We could instead leave stuff in $this->output and let the PW template (our controller) build output with PHP/HTML
$t = new StampTE($raw);
$t->inject('title', $page->title);
$t->inject('msg', $data['msg']);
if(!empty($this->kidOutput)){
$kidLayout = $t->get('kid'); //extract little subtemplate ('cut') to use for each message
foreach($this->kidOutput as $stuff){
$b = $kidLayout->copy(); //each message is put in a copy of subtemplate
$b->injectRaw('kidstuff',$stuff);
$t->selfkid->add($b); //completed subtemplate is pasted into master template
}
}
$this->output = $t->getString();
}
}//class
In this case we use StampTE to render the page with the sb3d_mvc_test.html and render the child pages with sb3d_mvc_testSub.html. It's setup to only render child pages from the top level but we could recurse more deeply (not tested) if there was a need to. More could be done. So far so good.
The render hook and the $options used by $page->render are key parts.
Lot's more to say/ask about PW but I'll dribble it out in future posts. Thanks.